Event-Driven Evolution with AI as my Partner in Design - Naomi Gotts
Watch on YouTubeVideo summary
Naomi Gotts opens her presentation by contextualizing the evolution of a legacy Laravel monolith at Tillow, a global gift card network that has grown alongside its business over the last decade. While the application carries significant technical debt and operates within a complex financial environment involving buyers, suppliers, and third-party integrations, it remains a critical asset responsible for processing over a billion pounds in sales annually. The core challenge driving this talk is the need to transition from an inadequate relational data model to an event-sourced architecture. This shift is necessary because the current system struggles with mutable history, constrained data structures, and limited traceability as new products like "Choice Plus" introduce complex transaction paths that span different times and actors.
To address these architectural challenges, the team embarked on a journey of domain discovery heavily supported by AI, specifically Google's Gemini. Naomi illustrates how AI served as an educational partner, helping engineers grasp complex financial concepts like double-entry accounting, journals, and ledgers through simple queries and scenario-based explanations. The team utilized AI to transcribe meetings with their finance department, summarize comparisons between various event streaming technologies like Kinesis and EventBridge, and even generate example code for experimentation. This approach allowed the engineering team to rapidly acquire the necessary domain knowledge to design events that accurately reflected financial realities, such as ensuring that every money movement event contained both debit and credit legs to maintain accounting integrity without floating-point errors.
The technical implementation focused on designing robust event structures and adhering to the transactional outbox pattern within Laravel to ensure data consistency. The team defined specific event types for allocation and settlement, using an "outbox" table to guarantee that database updates and event emissions happen atomically. AI played a crucial role in validating JSON schemas, suggesting naming conventions for event keys, and acting as a consumer to project future states based on event streams. Ultimately, the conclusion is that while AI significantly accelerated learning, evaluation, and coding tasks, it did not replace human judgment. The success of the project relied on continuous human conversations to verify AI-generated insights, solve complex problems, and maintain the craft of software development, proving that AI is a powerful support tool rather than a replacement for critical thinking and communication.
Read the full video transcript
A warm round of applause for Naomi and
her talk about event-driven evolution.
>> Which hand?
>> Thank you very much Dave and it's great
to be back here at PHP UK. Uh thanks to
all the organizers for once again
putting on a great conference and I for
one love a an interesting conference
venue. And who could have failed to
notice that massive piece of Roman wall
that's surrounding us today? A true
example of modern construction built
around but also embracing its legacy.
And whilst that Roman war might have a
legacy of 1,800 years, today I'm going
to talk to you about a Laravel
application with a legacy of a mere 10
human years. Although in computer years
it's more like 200. So it's sort of a
Victorian era infrastructure project.
But yes, this Laravel application is a
legacy monolith by our definitions. Um,
it has evolved with the business that it
serves over time.
It has its fair share of technical debt.
Would we call it award-winning?
Well, to coin Gary's phrase, it depends
on who you ask. Because whilst this
application might not be winning any
awards for clean code anytime soon,
last year this Laravel application put
through the sale of over1 billion pounds
worth of gift card sales.
So it does depend on who you ask.
Welcome then to the real world of
successful software development. one of
compromise, one of adaptation,
and one of evolution.
And it and I'm hopeful that some of you
here will resonate with this picture
because it likely means that you're
working for a company that is doing
something right. And it also likely
means that your job gives you the
challenge that is worth getting out of
bed in the morning. the type of
challenge that puts the word engineering
in software development. And today I'm
going to talk to you about a few of the
challenges that I and the team I work
with at Tillow have been facing and
tackling over the last year alongside
our new partner AI.
My name is Naomi and I'm a lead engineer
at Tillow, a global gift card network
connecting buyers with brands through
our gift card API.
And this is Anie, our Armatillo mascot.
He's very excited to be here as well.
Outside of the world of gift cards, I am
a big Formula 1 fan. I am a crafter and
I am also an adult fan of Lego. So, you
feel free to talk to me about any of
these things as well.
But back to the work stuff. And for the
last 5 years, I've been working with the
team at Tillow on our core Laravel
application. I've helped the product
evolve and I've watched the company grow
from strength to strength.
Throughout that time and actually
throughout my entire career, the
software development landscape has
changed massively. Gone are the days of
20 years ago when I'd be editing a file
on a live server in QFTP,
hitting the save button, and causing a
production white screen of death because
I forgot a semicolon.
That pace of change has kicked up
several gears just in the last year as
the AI has taken the software
development world by storm and caused
more hype than I've ever known anything
to in the industry.
Navigating that hype, especially when
it's all you see on social media, is not
easy, particularly when it promises that
it's going to change every aspect of the
job you have known and love for the last
20 years.
So, what does this mean for me?
Well, as I've literally just said,
change is nothing new. In fact, as the
old adage goes, it's the only constant.
And AI is just the latest tool that we
need to get to grips with.
This one does feel a little more
fundamental, however, and I will admit I
am a cautious adopter. But I am open to
seeing how it can improve my workflows
and processes.
>> Yeah.
>> And that's why I'm here today to share
some of my real world experiences of my
dabbings with AI as I worked with the
team at Tillow as we embarked on a
journey into the world of event
sourcing.
So today I'm going to take us through
the Tillow model brief introduction so
you can get a concept of the some of the
challenges we were facing. Then we'll
deep dive into events. We'll look at
some domain discovery, uh the design of
events and also code implementation
and I'll finish with some final
thoughts.
So the Till model
uh yeah to model gift at the center at
the heart of the Tillow model is the
Tillow gift card API. To the left we
have our buyers. They integrate with our
API. And to the right, we have our
suppliers. We integrate as suppliers to
obtain the gift cards that the buyers
are ordering. And of course, we have
multiple integrations to multiple third
party suppliers.
So this is our
this is our basic model of business.
It's a financial process and it's our
core um critical path.
And actually there's two transactions
going on here. There's the one on the
left between the buyer and there's the
one on the right between the supplier.
And at this simple stage of model we
store one row per end to end
transaction. So one row in our sales
table would contain the data for both
the buyer transaction with Till and
Tillow's subsequent transaction with the
buyer sorry with the supplier.
Now, as I've mentioned, our application
has evolved over time and over time
we've modified our product offering and
one of the things we have introduced
more recently is a product called Choice
Plus. Now, when a buyer purchases a
Choice Plus, we don't actually need to
reach out to as suppliers because we
issue Choice Plus ourselves. And the
choice plus is essentially a link, a URL
that the buyer then provides to their
recipient who can then take that URL,
load it in their browser and redeem to
the value of the link for one or more
gift cards of their choice.
So hopefully from this new picture, you
can start to see how maybe we're
changing a few things about how our our
basic model works here. We've still
actually got that one transaction
between the buyer and Tillow when they
purchase a link, but now we've got end
transactions occurring on the till
supplier side and not necessarily at the
time the buyer is purchasing the link
sometime later. So, we've got this other
path into our API from the recipient
path. So, I'm not going to get into the
detail of this, but I'm sure you can
imagine that this made the data storage
more complex.
And over time, what that's left with us
with is an inadequate model of our
financial business process.
Constrained data structures which were
hampering some of our internal teams
like finance, accounting, etc.
a mutable history because of course that
sales table's got a status column which
can be changed over time and limited
traceability between transactions that
were occurring. For example, link
transactions to do with uh redemption
choice plus for example. So what did we
want? Well, we wanted the opposite of
these things. We wanted a better model
of our financial business process. We
wanted a flexible data structure. We
wanted an immutable history and we
wanted full traceability.
So what we really really really wanted
was events or more specifically event
sourcing. The ability to construct the
state of your application at any given
moment in time from events and the data
that they carry.
Now, I don't know if how many of you in
the room have ventured into the world of
event- driven architectures of any kind,
but when you first out out on that
journey, the first thing you typically
do is look at the model that you need to
via events from. So, here we've got that
um the two journeys of the buyer
purchasing a choice plus and a recipient
redeeming that link for a gift card
brand.
And looking at those models we we need
to decide we need to identify what's
happening. What are the events occurring
in the system. So doing that we have a
choice plus ordered event where the
buyer orders from Till. We have the
choice plus issued event where Tillow
issues the uh choice plus to the buyer.
We then have uh the recipient requesting
redemption at which point Tillow needs
to reach out to the supplier to order a
gift card. The supplier issues the gift
card and Hill fulfills that redemption
request to the recipient.
And this is a great place to start if
you're thinking of going on the event
driven journey.
This is known as a process known as
eventtorming. And it's a brilliant um
process. It's like brainstorming but
with events. And you can do this with
both technical and non-technical
colleagues where you can draw out what
is happening in your system. And it
really helps to start defining the
events that you're going to need.
So I would advise anyone interested to
look into event storming um a bit more.
But we we we could draw out the events
that were occurring in our system. But
we needed to learn a hell of a lot more
uh on at the outset of our journey. We
needed to do some domain discovery and
we needed to do this in a couple of
ways. We needed to do this first on the
from the business domain side. So for us
that was the financial world and we also
needed to do this from the technical
domain side. We needed to learn a lot
more about events and event sourcing.
And how did we do this? Well, of course,
we worked with our teams internally um
with our finance team and in and within
our own engineering team. But this is
where we introduce our new friend
Gemini.
So Tillow has a uh Google workspace and
therefore we our access to Gemini was
the um easiest route in I guess to um to
use. So we use Gemini significantly
through this project and that's what
I'll be uh talking about using today.
So we're starting off with our domain
discovery and our business domain
specifically. Where did we start? Well,
we started with human conversations
because human conversation still
matters. Um, but it is quite useful to
have AI transcribe them. Actually, my
first sort of experience of having AI in
the workplace was seeing meeting notes
transcribed by and being completely
amazed at its ability to um pick up on
every little every little sort of thing
that we were talking about and then
summarize it. So, yeah, AI transcribed
meetings very useful. Um but through
these meetings we were starting to pick
up various terms, terminology, concepts
that of course we we had limited time
access with our finance team that so we
took away took away things that we
needed to investigate further things
like double entry accounting, the
journal, a ledger, cost of sales, all
sorts of things. So off the back of
these meetings, we then started to
explore subjects with with AI. some of
the first questions that we asked.
Please, can you explain in simple terms
what a financial ledger is? Yes, I'm
polite to my AI. Um, and then what is a
journal and how does it compare to the
ledger in a financial system
and over time we started to learn things
learned quite a lot actually.
So I'm going to start with a few things
that we learned um and specifically
first with the journal. So what is a
financial journal?
So at the bottom here you can see the
super simplified version of our Tillow
transactional flow where the buyer is
buying a gift card. And what we learned
about a journal was that it's a
chronological record of every financial
transaction that occurs on a system. So
in this example of our transactional
flow, there's two journal entries. The
first one where the buyer purchases from
Tillow. So it's my example here is
imagine you've got a10 face value gift
card. The buyer has a£10% discount so
they're paying £9 and till by the way
this is not real world would have a 50%
has got a 50% discount and so is paying
the supplier £5. So that's my example
use case here. So in that first journal
entry you see that the buyer is um
paying Tillow um debiting from their
buyer funds £9 into gift card sales of
£9. And the second journal entry sees uh
tillow incur a cost of goods sold of £5
and a liability to pay the supplier £5.
And if we Oh, so you can see that's the
first and the second um stage of our
transactional flow.
Um we might uh just extend that example.
So we've now imagine there's that whole
process happens twice. So 19th, 20th of
February, um the buyer has purchased a
gift card yesterday and and one again
today.
So that's what a financial journal looks
like.
And part of that financial journal is
that every entry in the journal must
have a debit and a credit. Well, and
here we see the debit of £9 and the
credit of £9. And this is so that they
don't lose track of any money um through
the system. And uh yeah that's the
concept of double entry accounting.
Next we learned about account types. So
you can see three different types of
accounts on screen right now. We've got
liability, income and expense. Liability
and income quite easy to understand from
my basic concept of knowledge of my own
bank account. I guess debiting and
crediting money. Um with a liability in
an income account. When you debit money
the balance goes down and when you
credit money the balance goes up. The
challenge comes when you start learning
about expense accounts where the reverse
is true. Um, but I typically think about
it as if you're spending money, then
you're debiting money and your expenses
have therefore gone up. Um, but yeah, we
learned about account types. And then
finally, we learned about a ledger and
how that is very much like your own bank
account. If you log into your online
banking and you see maybe you've got one
or more accounts there, it will give you
the overview of your debits and credits
that have occurred over time and your
your current available balance. And
that's what essentially a financial
ledger is. It's a summary of
any a given account. We've got two
accounts here as examples and the
balance of those accounts at any given
moment. So what did we learn from all of
this?
Well, the fundamental learnings we took
was that firstly the journal is
essentially an event store. Um, it's the
chronological storage of every
transaction that's occurred over time.
And the ledger is a projection. You can
produce this output based on the events
in your event store.
So we started to draw lines between the
business domain and the financial world
and our event domain and our techn our
tech our tech world.
So let's now think about that tech world
and where and how are we going to store
these events.
Well, where do we start with this? Well,
once again we started with human
conversations. Um it's super useful if
you are lucky enough to work with a team
to talk to that team and see what
experience they may have of um working
with different um systems in the past.
So from those conversations we had um
systems such as CFKA, Kinesis, Dynamob,
Eventbridge
come up and of course once we'd
collected those things together we could
then explore those things further. We
would ask questions such as please can
you provide a comparison of Amazon
Kinesis data streams and Amazon managed
CFKA streaming in 2025.
Um and what Gemini was super useful for
was producing summaries and comparisons.
So something like this. So where we've
got Cathfa Kinesis and event bridge
compared with various different aspects
and um obviously with more detailed uh
knowledge and information we were able
to ultimately make a decision. Spoiler
we went with EventBridge.
I will come back to that.
But in the meantime we did a lot of
experimenting. We experimented with
CFKA. We experimented with Kinesis. We
experimented with Event Bridge. And
Gemini was super useful once again in
providing example code that we could use
to get Kinesis running locally, send to
event bridge, etc., etc. As I said, in
the end, this is the the architecture
that we ultimately chose. We chose to uh
emit events from our Laravel application
to AWS event bridge from where it would
go into Kinesis Fire Hose and then onto
AWS S3 as our event store. And then as
an example at the end there we've got uh
Snowflake which is a data analysis
platform.
But today moving forwards from here I'm
literally just going to talk about this
bit the Laravel application and our
emission of events. So sorry for any of
you that were hoping I would go that way
but unfortunately that's not going to
that's not there's not time for that
today. So we're just going to stick with
the Laravel application and and sending
out to EventBridge.
So after all of that, we'd learned about
our financial domain. We'd learned about
our tech domain that we were working
with. We now needed to start thinking
about our event design. What on earth
were these events going to look like? So
we needed to think about event structure
and we needed to think about event
content.
Starting off with structure and when you
send event payloads into AWS event
bridge, the first thing it does is it
actually adds an envelope itself.
And you can see all the keys that of
data that it adds here. But you as the
sender have control over four of these
keys. You have control over detail type
which is essentially the name of your
event. The source which is some
identifier about where on your
application the event has come from a
list of AWS resources if if necessary
and also the detail which is super key
because that's where the bulk that's
where your main payload of data um will
be stored.
So we're now going to focus on that
detail what we put inside the detail.
So we then devised a tiller envelope and
it can comprise of the following keys.
So we start with an event ID. This being
a unique identifier so that any
consumers of the event can know if
they've seen this event before. We then
have a time stamp. Now it's interesting
to note you may have seen in the
previous uh slide for the AWS structure
that they put a time on the event. That
is the time that event hits the AWS
event bridge. That is not the time that
that event was actually produced. So our
time stamp here is to six decimal places
of when the event was produced within
our system. And this helps with things
like ordering if you're using a solution
like we are with with event brbridge.
The next thing is aggre aggregate ID.
Now this is the thing that's going to
help us solve our traceability of our
connected transactions. So in that
example say of a choice plus being
redeemed every transaction every event
that is fired from our system through
that process would carry the same
aggregate ID and so if you're working
with something like CFKA or Kinesis that
has shards or um
shards or the other word I can't
remember partitions that's it shards and
partitions then you can um fire and you
can direct any events with the same
aggregate ID down the same shard or
partition.
Um, and then we have a correlation ID.
This is much more about observability
and a single request response process.
So if you're working with uh multiple
services for example and we do have a
couple of different services that may be
used as part of our transactional flow
the originating service the one that's
hit first can generate a correlation ID
that it then passes to the next service
and then that passes through the request
the whole request life cycle. So you get
an observability um trait from that um
that is can be useful for um for
debugging etc.
So then we get to metadata and data and
this is where I'm going to focus from
here on in
metadata data
what goes where.
So in an event source system such as
this how much data should be cons
considered environmental business rules
versus data that is included as part of
an event.
Again, Gemini is super useful in
summarizing and really driving home the
purpose of each of these elements. So,
data being the facts, the single what
happened,
metadata being the context, the who,
where, how, why, the contextual
information of an event, and then also
important excluded. So, things that
shouldn't be included in an event. So
things like bis uh changing business
rules um example how a value is
calculated.
So now we have the basics of the idea of
our event structure. We now need to
start thinking about our event content.
And to do this we return back to our
financial journal and the idea that it
itself is a repres good representation
of an event store. So we've got two uh
pro two entries in our journal here. So
let's think about how we can represent
those entries as events.
So one of the first things we were
thinking about was right we got to get
this double entry accounting business
right otherwise our finance team won't
be happy with us. So do we do this? Do
we create a a different event for a
debit and then a credit? Immediate
answer we do definitely do not do this.
You do this. You ensure that a money
movement event contains both your debit
and your credit.
Um you also if you're working in a
financial system you'll notice here that
the amount is in integers. Do not work
in floating point numbers. If you if you
have done you will know why I am saying
this. If you haven't avoid avoid avoid
the hell that that can bring. So 900. So
we got to this point it's like okay
debit and credit but there was yet a one
more step of our learning that needed to
occur and this was key for our
understanding. So what we actually un
what we actually found out was that the
key principle of double entry accounting
is that the debits match the credits and
there can actually be multiple debits
and or credits in a money movement. So
the example on the screen now is an
example of something that we have in the
in the UK there's a concept of a
singlepurpose voucher for a gift card.
It's something that can only be used on
one particular product when redeemed and
is therefore subject to VAT at the point
of issuance.
So what you've got here is us debiting
the buyer funds of by £9 and then two
credits. one credit of £750 to Tillow's
gift card sales and another credit to an
input VAT account which is VAT that's
reclaimable um of £150 because that sale
is applicable has a VAT application to
it. And so what we ended up with in our
event content was an array of what we
refer to as money movement legs where
each leg was either a debit or a credit
and all the debits must equal all of the
credits. And if you do that you um meet
the criteria of double entry accounting.
Moving on, another thing Gemini was
super useful for was giving it
scenarios. We I'm sure you you will
understand that I've given you a very
basic overview of the till model today.
Under the hood, there are all sorts of
different scenarios occurring and this
is typical of most applications. We've
got different stock types. We've got a
bulk buy feature. We've got different
financial relationships. We've got the
cancellation process. We've got
different charging mechanisms with
suppliers. We've got intercomp payments
and we've got international payments.
And it was great to be able to give
Gemini scenarios of these these examples
and for it to produce back to us example
events as to well this is how you might
represent this this scenario in an event
in your event structure. Super useful.
Another thing that was very useful was
to get Gemini to act as a consumer of
your event. So you could ask Gemini to
produce a projection based on some
example events. Um and this was really
helpful so that we could see that what
we would what we would kind of envision
as maybe an output from our events was
actually possible to produce. So here
we've got if going back to our example
of those two purchases of gift cards,
you've got um what happens after each of
the four events have passed and what the
balance of each of those accounts is at
the end of that process. So Gemini can
act as a consumer. Very useful.
I couldn't put this presentation
together without mentioning naming
things because you know it's we're we're
developers and we like naming things.
Um,
so here's an example of where I use
Gemini to help me name something. Now,
we had we ended up with an account node
where um here we this is what we started
with classification and type. What I
wanted was to change the word
classification to type because that made
the most sense. The account type was
income. Um, but that meant I needed to
change the existing type key to
something else.
So please can we redraw our example
event and in the account element change
the classification key to type and
change the existing type key to
something that makes good sense.
The first thing it came up with was name
which I didn't like. So uh is there
another word other than name that we
could use in the account element key
that represents the value of the
specific type of account? It came up
with code and I was happier with that
and we actually did go with code. So
yeah, naming things.
Finally, the last thing I'm going to
mention about content is documentation.
So we use JSON schema to document our
structures and our content of our
events. And um I didn't know anything
about JSON schema before starting this
pro this project. Um but Gemini taught
me about it and it was also super useful
in validating the JSON schemas that we
produced as well.
So
now we know what the structure and the
content of our events are going to be.
It was time to turn our focus to code
implementation.
And again two lines of thought here.
Firstly event types and secondly event
emission.
So, event types. To explain this, I'm
going to take us back to our simple till
model of a buyer purchasing a gift card.
And I'm going to introduce you to the
four account types over on the right
hand side here of buyer funds, gift card
sales, cost of goods sold, and supplier
payable. And there starting balance. So,
the only account that's got a balance at
the start is the buyer funds. It's got a
a balance of 100. And we're going to
walk through this process. the buyer
purchasing a gift card and we're going
to see what happens to the balances of
those accounts on the right hand side.
So in before I get to that point, I'm
just going to say that previously we've
talked about there being two events
occurring in this flow. Now I'm going to
change that and I'm going to say there's
actually four and you shall see that as
I walk through this. So the first thing
that happens is the buyer gives us an
indication that they want to buy a gift
card. Now, at this point, they haven't
got the gift card yet, but they've given
us this indication that they want to buy
it. So, what we must do is we must debit
their buyer funds by £9 to prevent them
using that money on anything else. So,
they then have an allocated balance of 9
£9 and a available balance of £91.
Uh, equally, our gift card sale account
has a pending balance of £9.
Essentially, it's like a check that
hasn't cleared yet. It's it's incoming
money that hasn't quite landed yet. So,
before we can return the response to the
buyer, Tillow needs to obtain the gift
card. So, we now need to reach out to
the supplier with a supplier purchase
allocated event. So, we fire this before
we communicate with the third party API.
We this is our indication that we we are
accepting we're about to incur a cost or
expense of £5
and we'll need to be paying the supplier
£5. So you can see that both of those
cost of goods sold and supplier payable
have a pending balance of £5.
Remembering that that cost of goods sold
is an expense account where the balance
goes up when you take when you debit
money. Okay. So we now reach out to the
supplier and all's gone well and the spy
comes back. we can now settle that
supplier purchase event. Uh we can
settle that supplier purchase. So the
available balance of both those cost of
goods sold and supplier payable is now
five. And the final one we do is the
buyer order settled where we uh return
the gift card to the buyer. And so our
buyer funds no longer has an allocated
balance. It just has an available
balance of 91. And our gift card sales
now has a balance of £9.
And so when I talk about event types,
what I really mean is the concept of an
allocation event and a settlement event.
And that's what's that's what we are
representing here. So you allocate
money, it hasn't landed yet. When you've
done the thing that means the the money
has landed, you can settle the event.
There is one other event type that we
also have, which is allocation reversal.
I'm not going to get into that today,
but as you can probably imagine, we use
that when things don't go quite right.
and we need to reverse things. So, we're
just sticking to the happy path today.
But now we've looked at that, I want to
take us back to this very first event,
the buyer order allocated, the point at
which the buyer asks to buy a gift card.
Now, what do we do at this point when
the buyer asks us? Well, the very first
thing we do is ask the question, does
the buyer have enough money to do this?
Um obviously if they don't then we don't
uh we just give them a response in the
API saying that to the to that effect.
But let's say they do have enough money.
So the next thing that we need to do is
we need to reduce the buyer's balance
their in the database in their buy in
their buyer funds.
But we also need to send the buyer order
allocated event.
And we now introduce this um condition
that both of these things must be
successful or neither of them should
happen. Why we say this is we want to
ensure transactional consistency within
our data. We do not want to fire an
event to say that we've allocated this
buyer order and then the update to the
bio funds table fail. And we don't want
the update to the bio funds table to be
successful and the sending of the event
to fail. We want these two things to be
consistent.
And so we can't just dispatch this event
at the point we change the record for
the balance. Even if we do it after
commit in a database transaction, we
still don't actually know that that
event has gone where it needs to go. Um
so we can't do that.
Instead, therefore, we need to introduce
another database table, our events
outbox.
And this allows us to write our event to
that database table within the same
database transaction that we update our
buyer funds.
And then, of course, we can send our
event to event bridge from that outbox
table. But the fact the point of the
matter is we have written that event to
the events outbox. So we know it's in
it's where it needs to be in order to
ultimately be sent to event bridge. And
what you're looking at here
is the transactional outbox pattern and
it's really useful and we have made use
of it in our um implementation
and it looks a bit like this. simple
database transaction, two database
updates or an update and a create inside
the database transaction. And if either
fails, then neither of them are
successful.
And now we've got our event types and we
know the pattern that we need to adhere
to, it's time to return to our Laravel
application and think about the code
where we're going to need to implement
our events.
So the first thing that we discover in
our Laravel codebase is that the code
that has the useful data to create the
events is in and miles away from the
database transaction. So we're going to
need to emit the event.
Great. Okay. So we're going to need a
solution for this. Solution being we
need to prepare the event where we have
access to the useful data and we need to
send the event when we're inside that
database transaction.
And so we introduced the builder p we
made use of the builder pattern. We have
a manager class that makes use of in its
construct a builder class. And there are
two functions that are important here. a
prepare event function which is where
the manager uses the uh builder to
construct the prepared data and then a
send event function which is used to be
used within that database transaction
that is responsible for writing that
data to our outbox events table.
And we created a facade to um make the
use of our manager class slightly
easier. And um we can call the prepare
event in our code where we've got the
useful data and the send event where we
need to send it to the outbox
from where it can go to event bridge.
Now this event bridge code don't take
don't go and copy paste this. This is
just for example purposes only. Um but
essentially it it's a command script
that looks very very much like this.
What we're doing is we are querying the
uh outbox events table, collecting the
events we need to send, sending them to
event bridge using the AWS PHP SDK, and
then once we know they've been
successfully sent, we delete them from
the database table because we don't want
a database table to grow and grow and
grow continuous for and forever and
ever.
And that concludes my section on code
implementation which brings me to my
final thoughts.
So where does AI shine?
AI shines in in education. We learned so
much from just asking questions of
Gemini, getting examples from it, etc.
And it helps us with our domain
knowledge. No end.
AI also shines in evaluation.
It can review what you're thinking. It
can provide pros and cons to certain
solutions. It can give you alternatives
when you are stuck and can't think of
another option to the one that is the
one that's in your mind.
It can give you examples. It really
helped us when we were doing that
investigation experimentation phase with
CFKA Kinesis event bridge giving us
scripts and it was also really useful in
producing example projections
and it was helpful with validation as
well when we were building our um JSON
schemas that was super useful
however
I can't not mention this I'm always
absolutely Right. But
um no,
it it doesn't get things right every
time. Surprise, surprise. Um and you
should not lose your ability to think.
Super important. And human conversations
still matter. Yes, we we leveraged the
use of AI in this project, but it helped
us. It didn't deliver the project. What
glued everything together was those
human conversations. They still matter.
And so I'm going to leave you with a
thought about our craft as software
developers.
And I mentioned our craft in the
abstract for this talk and haven't
really mentioned it until now. So I
thought I'd better do that before the
end. Um, so yeah, our craft as software
developers, our craft is about more than
writing code, it's about complex problem
solving. It's about communication,
interpretation,
and designing solutions that meet the
needs of our users. Our craft relies
heavily on our ability to think
critically, to question, to reason about
things,
and to make decisions.
In my view, AI is a support for these
things, but it is not a replacement.
And as we continue to navigate this
brave new world of AI world, hyped world
of the software development, I for one
hope that we do not lose sight of this.
Thank you.
>> Thank you very much for that excellent
talk. And I think the positive at the
end cuz some of us might be worried that
we're going to lose our jobs, but I
think we're not because we still need
those skills that you uh um outlined. Um
if you do have any questions, we've got
time for a couple. Put it in the fleet
uh channel uh on Slack. Um I've got one.
How long do you think AI like as a rough
percentage, how much time do you think
it's saved or maybe more efficient?
Oh, I say um significantly in the area
of developing what our events were going
to look like. I'm not sure I could put
an exact percentage on it, but
a good chunk of time for sure. Yeah. Um
yeah,
we've got a question. Um did you
encounter any push back from the
financial department within your company
when you began relying on AI to explore
your domain? If so, how did you bring
them on board with the idea of using AI
in this critical business area?
>> Interestingly, no. Um, I think Tillow as
a business is actually very open to in
incorporating AI into our our day-to-day
practices. And I would say that we
leveraged AI to increase our learning at
a faster rate than we would otherwise
have been able to do. But we did fact
check with our finance team when we had
learned things. It wasn't just like, "Oh
yeah, we know what a financial ledger is
and a journal is now. We'll just carry
on." No, it wasn't like that. It was
very much like, "So, um, we've learn
we've learned these things. Can you
verify that what we're thinking is
actually correct here?" So, yeah, that
was again human conversation super
important.
>> Brilliant. I mean, they might ask AI as
well, but you know,
Um, okay. Right. Well, thank you very
much for that excellent talk.