rugyoga

rugyoga

My work at Lob involves a program called Dora that performs address verification. It validates addresses, repairs them to something valid or rejects them and tells you the issue. It’s basically a very long pipeline processing an Address struct with lots of rules and steps that gradually enrich the data structure as it passes along the pipeline.

The original authors have since moved on so we had to come up with techniques to understand why Dora makes the decisions and modifications it does.

To that end, I came up with Audit (hex,
github)

It operates by adding an extra field to the data structure of interest: __audit_trail__.
You then wrap your updates with the audit macro.
This will record the current file and line number (hence the use of a macro) and store the current version of the data structure.
The __audit_trail__ field is effectively a linked list history of every version of the
data structure you wrapped in audit.

The to_string method will take a struct with the __audit_trail__
and pretty print the list deltas and with the line of code that caused it
(as a github link, a filename/line number and a code snippet from the actual line in the file)
e.g. some example output:

github url: https://github.com/lob/dora/tree/leverage_audit_hex_package/lib/dora/.../standard.ex#L234
local path: lib/dora/.../standard.ex:234
code: address = %Address{audit(address) | primary_number: primary}
diff: [{[:primary_number], {:add, "18"}}]
=====
github url: https://github.com/lob/dora/tree/leverage_audit_hex_package/lib/dora/.../standard.ex#L228
local path: lib/dora/.../standard.ex:228
code: address = %Address{audit(address) | street_name: street}
diff: [{[:street_name], {:add, "BERNICE"}}]
=====
github url: https://github.com/lob/dora/tree/leverage_audit_hex_package/lib/dora/.../standard.ex#L217
local path: lib/dora/.../standard.ex:217
code: address = %Address{audit(address) | street_suffix: suffix}
diff: [{[:street_suffix], {:add, "ST"}}]

To kick the tires, add the following to your deps:

      {:audit, "~> 0.1.6"},

Add the __audit_trail__ field to your struct.
And modify your instances of:

%struct{ v | ... }

to be:

%struct{ audit(v) | ... }

then do the following to your resulting data structure:

r 
|> Audit.to_string()
|> IO.puts

Showing Posts 1 to 4

egze

egze

That is very cool and the usage seems quite nice.

Can you please edit the main post and include the GitHub Repo and a link to hex.pm? :wink:

egze

egze

Is there also a way to diff 2 structures, after the change has already happened?

rugyoga

rugyoga OP

Fixed.

rugyoga

rugyoga OP

Would adding a last_only: true option to to_string do what you want?

r |> Audit.to_string(last_only: true) |> IO.puts
github url: https://github.com/lob/dora/tree/leverage_audit_hex_package/lib/dora/.../standard.ex#L217
local path: lib/dora/.../standard.ex:217
code: address = %Address{audit(address) | street_suffix: suffix}
diff: [{[:street_suffix], {:add, "ST"}}]

i.e. it just stringifies the last diff.

You can access the diff engine directly with:

Audit.Delta.delta(a, b)

but you have to null out the __audit_trail__ field using Audit.unaudit_fun
before passing in the structs.

— All posts loaded —

Where Next? Top

Trending in Announcing Top

wojtekmach
Hey everyone! Req is an HTTP client for Elixir that I’ve been working on for quite some time. There is already a lot of HTTP clients out...
New
handnot2
Samly can be used to enable SAML 2.0 Single Sign On in a Plug/Phoenix application. This library uses Erlang esaml to provide plug enabl...
New
woylie
Flop is an Elixir library that applies filtering, ordering and pagination parameters to your Ecto queries. offset-based pagination with...
New
restlessronin
The repo is at GitHub - cyberchitta/openai_ex: Community maintained Elixir library for OpenAI API · GitHub. Docs are at OpenaiEx User Gu...
152 11030 135
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
fuelen
Hi all! I want to present a small library which provides a mix task for generating an Entity-Relationship Diagram for Ecto schemas. You...
New
anuaralfetahe
Hello Published a new library - ProcessHub! ProcessHub is a library designed to manage process distribution within the Elixir cluster. ...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
mudasobwa
I am seeing a lot of aplications of Argumentum ad Vericundiam in software discussions. They do link some piece of writing and point us to...
New
bartblast
Hey folks, I just published a post about Hologram’s funding and where the project goes next - the short version: Curiosum as Main Spons...
New
sorenone
Today we’re releasing Oban for Python. Not an Oban client in Python. Not a pythonx wrapper embedded in Elixir. Nope, it’s a fully operati...
New
AstonJ
This showed up on my feed.. anyone heard of it? Just hype? Ox Alpha is a reasoning model designed for coding, sustained ag...
New
sergio
It’s not that it’s vocabulary is too advanced. It’s something worse. I get lost trying to follow even a paragraph written by Claude. It’...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews