This repository is part of the Find Case Law project at The National Archives. For more information on the project, check the documentation.
An interface for editors to modify content metadata for the Find Case Law service. There are some differences in the UI depending on your user group.
This project uses Docker to create a consistent environment for local development.
On macOS and Windows, Docker requires Docker
Desktop to be installed. Linux
users should install the Docker engine using their distribution's package
manager or download a .deb or
.rpm
Once installed, we need to build our containers. We use
docker compose to orchestrate the
building of the project's containers:
django— The application container, built from a local dev Dockerfile by defaultpostgres— PostgreSQL databasemarklogic— Local MarkLogic instance (included in compose by default)e2e_tests— Playwright end-to-end tests (opt-in via--profile e2e_tests)
The base compose file uses the local dev Dockerfile (compose/local/django/Dockerfile). This stage installs all dependencies (including dev dependencies) but does not run the application server — instead it runs tail -f /dev/null so the container stays alive and you use fab run or docker exec to start the Django dev server, watch Sass, etc. Source code is mounted from the host (.:/app:z) so edits are reflected immediately without rebuilding.
This override file targets the production Dockerfile, which is the same image deployed to AWS ECS. Key differences from the local stage:
- No volume mounts — the app runs entirely from the files baked into the image, exactly as it would in production.
- Separate entrypoint and start scripts —
docker/entrypointwaits for Postgres and runs migrations, thendocker/startcompiles frontend assets (npm run build), collects static files (collectstatic), and starts gunicorn on port 5000. - Runs as the
djangouser — not root, matching the production security model. - Includes a healthcheck — polls
http://localhost:5000/checkto confirm the app is actually serving traffic, not just that the container started.
You won't use this during normal development, but it lets you catch production-only failures locally — for example, file permission issues, missing static assets, or entrypoint bugs that volume mounts would mask. CI runs this automatically on every push using docker compose ... up --build --wait to verify the production image builds and starts successfully before merging.
To verify the production image locally:
docker compose -f docker-compose.yml -f docker-compose.prod-test.yml up --build --waitNOTE: For any of the following commands to work, you must first install Fabric. Once installed, you can type fab -l to see a list of available commands.
NOTE: The .env.example file contains references to AWS tokens, such as AWS_ACCESS_KEY_ID, AWS_SECRET_KEY and AWS_ENDPOINT_URL. These should only be populated if you are testing locally with localstack (though the values do not matter, you can use anything). Leaving them blank will default to your configured AWS account.
$ cp .env.example .envThis app connects to the MarkLogic database defined in ds-find-caselaw-docs/marklogic.
A basic local MarkLogic instance is included in docker-compose.yml and starts automatically with fab run / docker compose up. This is enough to get the application running without needing a separate repo or VPN access, but the local MarkLogic setup may need further development — see the ds-find-caselaw-docs/marklogic repo for full configuration details.
Alternatively, TNA/dxw developers can connect to the shared staging MarkLogic database via VPN by setting MARKLOGIC_HOST, MARKLOGIC_USER, and MARKLOGIC_PASSWORD in your .env file.
The compose files in this repo and in other caselaw services share an external network named caselaw. Create it if it does not yet exist:
docker network create caselaw$ fab buildIf you have previously run the ds-caselaw-public-ui app you may need to stop its containers (except Marklogic) before you can run these.
$ fab start$ fab sh
root# ./manage.py createsuperuser
root# exit
$$ fab runNOTE: Compiled CSS is not included and therefore needs to be built initially, and after each git pull.
While it's handy to be able to access the django container via a shell and interact with it directly, sometimes all you want is to view the site in a web browser. In these cases, you can use:
$ fab runThis command takes care of the following:
- Starting all of the necessary Docker containers
- Installing any new python dependencies
- Applying any new database migrations
- Starting the Django development server
- Watching the Sass and JavaScript files for changes
You can then access the site in your browser as usual:
(NOTE: The output of the asset and JS builds are logged in the ./assets.log file)
When starting up, if you encounter an error message like this:
ERROR: for postgres Cannot start service postgres: driver failed programming external connectivity on endpoint ds-caselaw-editor-ui_postgres_1 (0fb7572d583761d3a348e8fd9139b0007638a17c6f91b15e8678f2575f94ffa7): Bind for 0.0.0.0:5432 failed: port is already allocated
It's because the public UI project is still running, you'll need to reopen that project and run the command fab stop.
Now go back to the Editor UI project and use the same command fab stop.
Now you can restart the project up again with fab run.
The button that submits an edited document needs S3 and SNS services to function (as it copies files across and notifies the enrichment service that it might have been published).
Before you do this you will need to pip install awscli-local and you will probably want version 1 of the AWS CLI
tools. Version 2 may cause things to explode in unexpected ways, as it's not fully supported by LocalStack.
Start it up by running from the ds-caselaw-ingester repo:
docker compose up -dand then, in this repo (on your machine, not the Docker image):
script/setup-localstack.shThat script will create in localstack a caselaw-stg-judgment-updated SNS
topic and public- and private-asset-buckets for S3.
$ fab testYou can also pass arguments to pytest
$ fab test --test="-k specific_test_to_run"To use this, you will need to install pre-commit on your development machine, typically using pip install pre-commit.
Install the git hooks configured in .pre-commit-config.yaml with:
pre-commit install
This will set up various checks including Python linting and style checks when you commit and push to the repo and alert you to any linting issues that will cause CI to fail.
Any commit that's merged to main needs to be signed, to ensure the identity of the author is who they say they are.
We recommend signing with your ssh key, as it's probably the easiest method of doing so. Assuming you already have an ssh key created, just follow the following steps:
- Add your SSH key as a signing key in your github account - note this is different to an authentication key, which you likely already have set up. You can use the same key for both purposes, but you need to add it separately for each one twice.
- In your terminal, run the following commands. This assumes you want to set up commit signing by default for all repositories. If you don't want this for whatever, reason, leave out the
--globalflag (but in that case you'll have to remember to repeat these steps in every TNA repository you work on):- Enable signing with
git config --global commit.gpgsign true - Specify that we'll use SSH for signing with:
git config --global gpg.format ssh - Specify the key you'll use to sign. If it's not id_rsa.pub, give the correct path here:
git config --global user.signingkey ~/.ssh/id_rsa.pub
- Enable signing with
If you have already made some unsigned commits on a branch before setting up signing, you'll need to sign them before they can be merged. You can do this by rebasing, typically using for example git rebase --force-rebase main then doing a force push. Care should obviously be taken here however, especially if there's anyone else working on your branch!
Included in this repository is:
- Webpack and Babel for transpiling JavaScript
- Sass for compiling CSS
- Ensure you have NodeJS & NPM installed.
- To watch and build the site SASS, run
npm run start-sass - To modify styles, navigate to the
sassfolder in your editor.
To use a local development copy of nationalarchives/ds-caselaw-frontend, for example to use your local copy of the shared CSS instead of what's currently in it's github repo's main branch:
npm link ../path/to/your/copy/nationalarchives/ds-caselaw-frontendTo stop using your local copy, you can then run:
npm unlink ../path/to/your/copy/nationalarchives/ds-caselaw-frontend- In a new terminal session run
npm run start-scriptsto kick off a Webpack watch task
By default, When encountering an undefined variable in a template, Django will return an empty string, which is useful in production to avoid unnecessary 500 errors, but not so useful in development, as it makes things difficult to debug.
In order to debug template problems, you can add TEMPLATE_DEBUG=1 to your .env file, and undefined variables will show up as eg {{ variable_name }}.
To login or signup to the staging application, go to http://localhost:3000/accounts/login. From there you will be able to log in to an existing account.
To set up the first administrator account or recreate an account if the login credentials no longer work, run the following procedure:
- Make sure that both the Docker container and the VPN are running.
- Check that the Fab Build is also running by opening a terminal window and typing
fab start, this should return a message to say it's up to date. - Now open a new terminal window and create a new superuser account by running the following commands:
- Type
docker compose exec django bashand hit return - Now type
python manage.py createsuperuserand hit return, This will show the set username ofroot. You can change this to something else to make it more personal – but it can be left as it is. If you want to change it, type in your new username and hit return if you are happy with leaving it asrootalso just hit return. - It will now ask you for your email address, type this in and hit return.
- Lastly, you will require a password, There are no rules to follow so it can be what you want. You will need to re-type your password so that it is validated.
- Success – your superuser account is now created.
Head back over to
http://localhost:3000/accounts/loginand input your new login credentials to gain access to the Editor UI local instance.
Currently there is no way for the editors to delete a judgment from the production site, if the judgment has been assigned a neutral citation number. Until this functionality is built into the editor UI, judgments need to be deleted manually. Editors will create a Trello ticket with the URI of the judgment they need removed from the site.
To do this:
- Log in to the production XQuery console
- Get the XQuery to delete a judgment from the API Client (Often there is a pre-existing tab in the XQuery console with this in)
- Add the URI of the judgment to delete to the script; e.g.
declare variable $uri := '<your URI here>'. Don't forget URIs in Marklogic begin with a slash and end in.xml - Run the script, if it is successful it will return no output
See the deployment documentation.