Swansea University Legal Innovation Lab Wales

Legal Innovation Lab Wales

Developer Page

Welcome to the Legal Innovation Lab developer page. Here you'll find information about projects we've worked on, information about our approach to development and our developer blog.
If you have a project idea (or thoughts or questions), please get in touch as we'd love to talk!


These are the projects which we have worked on or contributed to.

Scenario Platform

An app which facilitates the creation and practice of interactive scenarios for extending theory knowledge into practice.

With a brief from Dr Matthew Parry an app was developed which allowed admin users to create and manage scenarios which have a branching, non-linear, structure and where each answer could influence a range of custom measures. Examples include interviewing a client within a legal setting. Measuring factors such as compliance, client understanding and approach. Approaching a medical situation and measuring on proper procedure and situational understanding.

Include Journey

A web app to help prison leavers on their rehabilitation journey

Working with Dr Gemma Morgan alongside the team members from Include and the service users they walk alongside, an application has been designed and built to help facilitate the work that Include do. The app comprises two sides of the same coin, one side for team members, the other for the service users. Team members have an overview of all the users and can delve into specific aspects of their journey. Users can use the application to record their wellbeing, to write a journal, keep track of their appointments, contacts and goals. All of these activities are encouraged using simple gamification.


A web interface to a ML classification model for identifying conversations which contain grooming as part of the Detecting Resistance Against Grooming ONline (DRAGON) Project.

As part of the DRAGON project led by Professor Nuria Lorenzo-Dus, we developed an interface that allows law enforcement officers to upload and process conversations which have been extracted from suspects devices. The model identifies grooming tactics in the conversations and gives an overall suspicion score to aid officers in the evidence gathering process. The interface allows conversations to be collated and viewed based on the participants, platform or suspicion score.


An app which will relay specialist knowledge to child safeguarding professionals about groomers’ and children’s communicative behaviour during online grooming through a learning portal.

Built using an extendable web application framework, the Shield app will allow users to progress though 10 training modules. The modules feature a range of learning from overviews to deep dives into specific topics, they learning is presented in a variety of ways and consolidated with assessments at the end of each module. Organisation admins can manage users and view their progress.

Expertise Directory

A web scraping tool that collates the "Areas Of Expertise" for Swansea University academic staff across 3 colleges, the information is then provided in a searchable and filterable web interface.

Using a Python script which runs daily using GitHub Actions, data is gathered from the public staff profiles on Swansea.ac.uk. This is then collated into a single file and hosted in a public interface. This interface allows exploration of the areas of expertise to match with users with similar areas of expertise. The entire app is based on the university website structure and reliant on staff providing their areas of expertise. If the web structure changes this app will break.

The Wellbeing Directory

A web application for people seeking services to suit their wellbeing needs with special attention paid to being able to find services within your local area.

Following several demos of the Include Journey app it became apparent to Dr Gemma Morgan and our team that there was a lack of discoverability for wellbeing services in general. With this project we sought to provide a platform to aid in the discovery process and assist people in finding services that can help them. After one short month this project was designed, implemented, and released. The data is now maintained by colleagues.

Tagging Case Law

A web interface for displaying a collection of case law extracted from PDF documents into an ontology via natural language processing.

The creation of the ontology via NLP extraction on the case law PDF documents was initially done by Livio Robaldo and our work built on this by taking the resultant XML and ontology model and producing the web interface as well as API endpoints. the information is presented in a responsive web design along with the ontological dependencies between them via the entities involved such as the judges, lawyers, courts and persons (though this latter entity was removed over GDPR concerns).

Privacy Demo

Human readable information for humans.

Privacy Policies suck. No one wants to read them. We’re trying to make them better with this idea.

Human readable information for humans and a link to a broad policy available for those who want and need it.

Regulatory Navigation Tool

LawtechUK launched an interactive PDF to help “those innovating in law to navigate the regulatory landscape”. You can read about it and see the original PDF tool here

This original is a wealth of knowledge and an incredible tool, however we discovered it had several compatibility issues in a range of browsers.

In a 1-day build, Ieuan took this tool and rebuilt it with ReactJS. After checking with LawtechUK its now live on the web.

KIID Onboarding Tool

Document automation tool, with NLP.

A web interface and API endpoint to an NLP Java application developed by Livio Robaldo that can programmatically extract features from Key Investor Information Documents and return these features in a JSON structure. Built in collaboration with Zeidler group.

Developer Blog

A space for our development team to write about topics which interest them, share our ideas and discuss what we’re working on.

Our Approach

This section of articles talks about the way we work in the development team at the Legal Innovation Lab Wales. We're a small team with big aspirations and we're trying to do things right. There are lot of different opinions when it comes to best-practices, these articles talk about our approach. You can also find the posts in our blog.

Select an article to read using the links below.

| |

Note: These are living guides. We follow these processes on a day-to-day basis. We will tweak and update them as we go along and learn form our mistakes.

How We Build a Prototype

We are a small team, doing big things. We need to be smart about our approach to software development, work hard but also work smart. Our approach to development is based off “Getting Real”, a methodology used by Basecamp. Their full book is available online.

There are some core principles from Getting Real which we follow as we build software. I’ll describe these below, however our methodology is not identical to that in the book.

A note on the authors of Getting Real

It’s unlikely that anyone is ever going to agree fully with someone else, and it is important to acknowledge and understand that. I only mention this due to some of the controversy which Basecamp was involved in recently. (Search The Verge for “Basecamp” if you want to get up to speed). While, I personally don’t agree with the policy changes they implemented, I do strongly agree with a lot of the principles in Getting Real.

Why do we take this approach?

Most of our work is developing prototypes which can be used as proof of concepts to show a solution to a specific problem. These prototypes are simple and focused around solving a specific problem. We are not trying to build the next Facebook or Amazon. We are trying to engineer a novel solution which will be useful to the people that experience the need for it.

This need lends itself to this process and by directing our focus in this way, we can build something quickly which can illustrate an idea without worrying about the details or dealing with potential problems before they need to be dealt with. This approach and modern software tooling, facilitates quick deployments and live updates. It makes it easy to iterate and lowers the cost of changes.

Why don’t you just do “Agile”?

With Agile, you normally work in continual 2-week sprints, led by a Scrum Master or Agile Delivery Manager, and often spend at least one day out of that fortnight on “ceremonies”. The features that are worked on are normally identified well in advance by a product manager, then designed by a designer before making it into sprint planning.

I’m aware that I’m mixing terminologies and that there is a vast depth here, but that’s the problem. We don’t need to go into all the complexity of Agile, Scrum, Kanban. We want to keep things simple, both in the code we write and the process we follow when writing it!

Agile was supposed to liberate software developers from process, but (at least from my experience, most of the time) its current form reduces developers to ticket machines. When you run a sprint, what's the first thing you do when you finish? You stop and catch your breath. Agile's perpetual two-week sprints don't allow for that pause, instead focusing on velocity of completing tasks, the factory line.

With a small team, each team member needs to wear many hats. Each of us needs to act as a designer, developer, product and project manager. We have pretty complete autonomy and responsibility for what we produce. We don't have the luxury of the additional roles which normally come to facilitate the Agile process.

Quick Disclaimer

To complement the “Caveats, disclaimers, and other pre-emptive” strikes section in Getting Real:

This is not a post which is saying this is the best way to develop software, although I do think it's one of the best ways. We are not saying that this approach will work for you, although it might. This is just giving an explanation of the way which we have found works for us in the Legal Innovation Lab Wales.

This is also only our standard approach, we don’t follow this to the letter every time. Not every project we work on fits this mould. We’ll always prefer a flexible, adaptable approach which suits the project rather than trying to force a square peg into a round hole!

What is our approach?

The core principle is that we want to build something; something that works, something that looks and feels good.


As with any project, we start with planning. Working with the stakeholders, we'll outline their idea. Look at what problem it is trying to solve and how. We will help the stakeholders understand what’s possible, what would be unfeasible and suggest ways which we could engineer something to enhance their idea.

We'll then look at the specific features which the solution needs, we'll normally categorise this using a MoSCoW. This determines the hierarchy of the requirements and informs which ones we need to focus on first. We can discuss with the stakeholders the technical difficulty of the features they would like. Often features are far easier, or far more challenging, than they might seem at first.

We don’t want to reinvent the wheel. We don’t want to build something which already exists. Before we build anything, we want find what existing solutions there are, look at what they do and what they don’t. What is good about that solution and what is not? What features should we share and what additional features do we need to create?

Planning is all about collaboration and conversation.

The outcome from the planning is an agreed upon set of core features which we think should be achievable in a 6-week development cycle. We work on the opinion that it's much better to build less features but to build them better.


We’ll then spend 6 weeks engineering those features. When starting a project from scratch the first thing we'll do is create Entity-Relationship Diagrams (ERDs), this data structure informs the design of the back-end. Following that, we'll normally spin up a framework, most commonly Ruby on Rails, but this will vary depending on the project.

With the basics in place, we can then split various area of the project up and work on them in parallel, collaborating and peer reviewing our code as we go. We’ll also check in periodically with the stakeholders to gain their input into the direction of what we’re building.

You can find out more about how we actually build features in this article.

We want to build it well, so that it is extensible and maintainable. We are unlikely to be the ones who develop this software in the future, but we want to leave our code in a state that whoever comes along has an easy job, and we want to be proud of what we’ve built.

This means that we would rather take longer on each feature, ensuring its quality and reduce the overall scope of what we build than half-build lots of features.

This is where one of my favourite philosophies comes in. Build Something Beautiful. This refers to both the UI and the code that you're writing. It's much nicer to test a front end which is pleasant to look at. It's much easier to debug code which is clean, well formatted and, well, beautiful. In the early stages of development its important not to worry too much about the finer details, but I still believe its worth investing the time to get the interface looking like something your proud of. The same principles apply to the code you're writing.

If you think we can help you develop a prototype, please get in touch!

How To Build a Feature

A brief best-practice guide for how we build features at the Legal Innovation Lab Wales

Note: This is a living guide. We follow these steps on a day-to-day basis. We will tweak and update this guide as we go along and learn form our mistakes

Start on Jira

After a feature is outlined or described by stakeholders it will be added to the Backlog column on Jira. When creating the ticket, as much detail as possible should be given. We won’t always be able to provide a full user story, but give as much information as you can as early as you can. The backlog column is roughly prioritised with the more urgent tasks appearing towards the top.

When you come towards the end of the task you are working on, select a ticket from the top of the Backlog, assign it to yourself and move it to Next Up.

With the ticket in Next Up,there is the opportunity to refine and expand the feature description. The aim is to fully describe the feature as well as we can and how it is going to look when finished. You can ask for input from one or all of the rest of the team.

When you are happy with the detail on the ticket, move the ticket to In Progress.

Developing the Feature

Git Guides: How and Why, Handbook

Ensure your local branches are up to date then create a new branch for your work. The branch name should be prefixed with the type of ticket and then start with the ticket ID and the ticket title.

Branch prefixes include: feature/, bugfix/, hotfix/, refactor/ , other/.

Examples: feature/dt-124-how-to-build-features, bugfix/sp-206-fix-broken-thing, hotfix/fix-for-this-issue

When working on a ticket, commit regularly. Each commit should contain one discrete change / improvement and should be made when the codebase is in a state which you want to remember. Each commit which directly relates to the task should have the ticket ID at the start of it.

As you are working on the feature, build it to the best of your ability, leveraging your experience, creativity and ingenuity. If something comes up which you are uncertain about, or if you think of something which could be a good addition to the feature, go back to the ticket on Jira and ask about it there.

There are a couple of principles which we try and follow when building features. Most of which are common software development principles: KISS, SRP, and DRY. One that is less common is what I call "Build Something Beautiful". This realates to the principle Rails' docterine of optimising for developer happiness.

Build Something Beautiful is about writing beautiful code, but more importantly about thinking about the interface first. No one really likes testing functionality on something which has no styling, so its worth investing the time to consider the interface first and style the project earlier rather than later. Make it beautiful! The interface is the product, its what the end user is going to see. It's going to constantly be revised through the process but having something there from the start makes everything else easier and more enjoyable

When you’ve finished work on the ticket, push your code to GitHub and create a pull request (PR). Your PR title should contain the ticket ID and a short title, probably similar to the ticket title. The description of your PR should be an explanation of what you have done and how, including screenshots if there is a front end / UI component. Then request a review from the rest of the team. PRs are designed for the team to check your code makes sense, does everything its supposed to and meets our standards.

From the “How and Why” Guide:

Once a Pull Request has been opened, the person or team reviewing your changes may have questions or comments. Perhaps the coding style doesn't match project guidelines, the change is missing unit tests, or maybe everything looks great and props are in order. Pull Requests are designed to encourage and capture this type of conversation.

You can also continue to push to your branch in light of discussion and feedback about your commits. If someone comments that you forgot to do something or if there is a bug in the code, you can fix it in your branch and push up the change. GitHub will show your new commits and any additional feedback you may receive in the unified Pull Request view.”

We strongly recommend reading the guides, if you have questions following that don't hesitate to get in touch.

Back on Jira

When you code is up for PR, move the ticket to Pending Review. Now you should pick another ticket from the Backlog and move it to Next Up. You can also spend some time reviewing any other open PRs.

GitHub - Reviewing Code

When reviewing PRs we should do several things:

  1. Go through all the code changes, leave comments
    1. anywhere there is something you don’t understand
    2. anywhere that you think something could be improved
  2. Pull the branch and run it locally, double check everything works as intended.
  3. Think about what has been built, if it works as intended, meets the requirements and if there are any ways it could be improved. If you have any suggestions try and explain the How and Why in as much detail as possible.

You can always get involved and collaborate. If there is a small bugfix, you can make the change and push the code onto the branch. If there are design or feature changes you think could work better, create another branch and an additional PR back to the feature branch.

There’s no rule that says the person who raises the PR has to be the sole contributor to it. If there is agreement about a feature change, it might make more sense for the person who has the vision for the changes to write the code, not the person who started on the branch.

Tools We Use

This aims to give an overview of the tools we use and the way we use them to build software in the Legal Innovation Lab Wales. It describes a current state, things are likely to change over time, and we’ll try to keep this up to date as things evolve.

Update December 2021: We've updated the way we use a few of our tools and added a few more to our toolbelt. The original article is still available in our blog archive.

Office / Outlook

The University has an Office 365 subscription for all staff. We use Outlook for emails and the Outlook calendar meetings/events.


As part of the office package we use Teams as our primary communication platform. We use it in a couple of different ways. The main "Team" is used to organise documents by the project team.


The main communication in teams happens in chats. These are informal conversations about a range of topics with specific people or groups of people. We have a DevTeam chat and a LegalTech chat which are used most frequently.


Channels are a more structured way of having conversations around a specific topic. The nature of channels is more persistent and asynchronous. We should use channels for discussions around specific topics which aren’t necessarily related to a task in Jira.


Notion is our main knowledge base. We have a range of pages relating to specific projects as well as spaces for each of our developers to work on blogs and other writing. There are also pages for to help track the dev team's priorities and progress.

We also have an Ongoing Projects Board on Notion, which the wider team use to manage different projects, and their progress.


We use LucidChart as part of the project planning process. We create ERDs and other technical drawings on Lucid. The ERDs serve as a reference for the database designs in our apps and will be kept up to date during development.

Lucid is also great for other diagrams and drawings. The project lifecycle document as well as some specific user flow documents have been created on Lucid.


We use Figma for designing user interfaces. We don't use this religiously, but when we need to showcase designs to stakeholders before we create them in code, Figma is the best tool for the job.


The dev team no longer uses Microsoft Planner


Jira is our main software development project management tool. This is where the day-to-day of our dev team happens. We have several boards where individual cards correspond to individual tasks. These cards are often referred to interchangeably as tasks, issues or tickets.

The main Dev Team board is for general tasks which don’t relate to any specific project, or relate to projects which are not mature enough to warrant their own board. We also have separate boards for other ongoing projects.

On these project specific boards, each issue card should relate to one specific feature, bug or task. This normally equates to one Pull Request on GitHub.

Jira is also where we have discussions related to specific tasks. Comments can guide the conversation while the description can be updated collaboratively with improvements from the comments.


We use GitHub for version control, code repositories and peer reviews of our code.

For more information on how we use GitHub, Jira, and build features see “How to Build a Feature”


As with the rest of the faculty, we use Calamari for time off booking and management.


As well as Teams video meetings, we often use Zoom for video conferencing.


Most of our accounts require secure passwords and MFA. I personally use1Password for password and OTP management. Although other FOSS alternatives are available such as LastPass, Bitwarden and Authy.

Tech Stack

The following tools are more specific to our software tech stack. We have a preference for Rails due to its developer-friendliness but do use Python and Java in some projects. We use the following tools as part or our infrastructure stack.


Netlify is one of the tools we use for static site hosting. The Developer page is hosted here. If we need to spin up any other static sites, Netlify is something we would consider. Other than Netlify, we would consider using Cloudflare


Cloudflare forms part of our technical stack. We use Cloudflare to manage the DNS for legaltech.wales domain and all subdomains. Cloudflare does all the things that they do really well; caching, firewalls, security and more. For most of our prototypes, Cloudflare sits between the user and Heroku.


We leverage Heroku's PaaS to host the infrastructure our most of our prototypes, any full-stack apps are likely to live on Heroku.


Ruby.ci does some automated checks on our code to help use maintain high quality.


As part of our prototypes, we use Sendgrid to power email sending from our Rails apps.

Other Helpful Bits

Javascript for Hideable Sections

Similar to bootstrap collapse, but way simpler.

function collapseElement(input) {
    const section = document.querySelector(input);

<a onclick="collapseElement('#note')">Title of what to reveal <i class="fas fa-chevron-down"></i></a>
<p id="note" class="hideable">Revealable text content</p>

.collapse {
  max-height: 0;
  overflow: hidden;
  transition: all .5s cubic-bezier(0, 1, 0, 1);
    max-height: 20rem;
    transition: all .5s ease-in-out;

Show link icon on hover and copy anchor link to clipboard when clicked

function copyText(input) {
    const text = document.createElement('textarea');
    text.value = "https://developer.legaltech.wales" + input

<h3 id="copy-anchor-links">Javascript for copying anchor links on click
    <button class="copyLink" onclick="copyText('#copy-anchor-links')"><i class="fas fa-link"></i></button>

  h2, h3 {
    font-weight: 700;
    .link-spacer {
      margin-left: 45px;

    button {
      visibility: hidden;
      border: none;

    &:hover {
      button {
        visibility: visible;
        color: $dark-gray;
        background-color: inherit;

Javascript for Swapping Between Welsh and English

Used to power the language switcher on the LegalTech.Wales Squarespace site

Usage Note: add class="english-lang" to main body and class="english-lang" and class="welsh-lang hidden" to the respective sections. Then create a button to call the JS.

Welsh Mode Toggle
function toggleLanguageMode () {
    // Toggle from English to Welsh
    var welshSections = document.getElementsByClassName("welsh-lang");
    var englishSections = document.getElementsByClassName( "english-lang");
    if ((document.getElementsByTagName("BODY")[0].className) === 'english-lang') {
        // Update Tag in Body declaration
        // Hide English and un-hide Welsh
        [].forEach.call(englishSections, function(add_hidden){

        [].forEach.call(welshSections, function(rm_hidden){

    // Toggle from Welsh To English
    else if ((document.getElementsByTagName("BODY")[0].className) === 'welsh-lang') {
        // Update Tag in Body declaration
        // Hide Welsh and un-hide English
        [].forEach.call(welshSections, function(add_hidden){

        [].forEach.call(englishSections, function(rm_hidden){
    } else {
        alert("Somethings gone wrong with the Language, Sorry!")

Javascript for Theme Toggle

Used to power the theme toggle on the developer blog

Usage: Use css classes .dark-mode and .light-mode to define the styles. Example is below the js. The script first checks to see if there is a local theme preference stored, then looks for any OS preference. When the toggle button is clicked it stores the preference in local storage

const btn = document.querySelector("#theme-toggle");
// check to see if OS preferences for light or dark mode
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
const prefersLightScheme = window.matchMedia("(prefers-color-scheme: light)");

// check to see if local storage has a theme preference
let currentTheme = localStorage.getItem("theme");

function setTheme() {
    //if no local storage check against system preferences
    if (currentTheme === null) {
        if (prefersDarkScheme.matches) {
            currentTheme = "dark"
        } else if (prefersLightScheme.matches) {
            currentTheme = "light"
        } else {
            // if no preferences, default to dark theme
            currentTheme = "dark"
    } else if (currentTheme === "dark") {
    } else if (currentTheme === "light") {

btn.addEventListener("click", function () {
    if (currentTheme === "dark") {
        currentTheme = "light"
    } else {
        currentTheme = "dark";
    localStorage.setItem("theme", currentTheme);



&.dark-mode {
  background-color: $dark;
  background: $dark-background;
  color: $ink-light;

  .dark {
    display: block;

  .light {
    display: none;

  nav {
    a, button {
      background: #ffffffe6;
      color: $dark-gray;

    a:hover {
      color: $ink-dark;
      background: #fff;

    button:hover {
      color: $ink-dark;
      background: $light-background;

  .author {
    color: $medium-gray;

&.light-mode {
  background-color: $gray;
  background: $light-background;
  color: $ink-dark;

  .light {
    display: block;

  .dark {
    display: none;

  .lab-logo {
    background-color: $dark;
    background: $dark-background;
    -webkit-box-shadow: 0 5px 10px 10px $dark;
    box-shadow: 0 5px 10px 10px $dark;

  nav {
    a, button {
      background: $dark-gray;
      color: $ink-light;

    a:hover {
      color: $dark;

    button:hover {
      color: $ink-light;
      background: $dark-background;

  .author {
    color: $dark-gray;