Skip to content

Draft: Refactor/uuid use wrapped type

Status

Does not currently compile; work in progress.

HEAD^ (e9045567) currently compiles and runs but only replaces clientUuid and userUuid. HEAD is working on replacing volumeUuid but that change is much bigger and I ran out of time.

Several places need preliminary refactorings where we currently smash two behaviors: UUIDs and sentinel values such as "auto" to mean "generate one for me." We will need to write custom parsers for the input element onChange events and turn those into a union type.

type UuidChoice
 = UuidString String
 | AutoGenerate

Some places currently smash together an empty string and a UUID string to avoid Maybe. These also could use a preliminary refactoring. Doing these refactors in this or in !785 (closed) are leading to MR bloat and can each be independently done without hampering the UUID work.

Overview

Alternative to !785 (closed)

Alternative to !554 (closed)

Wraps UUID type in a phantom type wrapper and preserves API-sourced string value of UUID.

Provides a path for varying levels of strictness in validation:

  • Prevent accepting UUID strings that don't validate
  • Accept all UUID strings but track if they validate; warn the user that something is wrong but continue using the values.
  • Accept all UUID strings and "pass the buck" onto API call endpoints to validate.

Why?

Turns out that structural UUID handling is complicated. We currently receive some invalid UUID values that are handed out by some API endpoints. Also, different endpoints in testing appear to have different strict preferences for the formatting of the UUIDs. That is, where I expected a given API to want a UUID without dashes, it required the dashes. Another similar endpoint wants the opposite.

Preserving them as strings avoids changing app behavior and introducing subtle bugs that may not immediately appear (because the particular API endpoint isn't hit frequently enough) while giving us additional safety against using one kind of UUID for another kind. For example, handing out model.volumeUuid when we're supposed to hand out model.volumeSnapshotUuid. This is currently conflated with the type alias Uuid = String type but can be enforced with type Uuid a = Uuid String

How to Test

Screenshots

Edited by Chris Martin

Merge request reports