When I began tracing complaints scattered across many modules, I realised they all pointed to the same root: there was no transaction-identity foundation anyone could trust. This is how I built one from the ground up.
Each exercises a different muscle from the flagship — giving non-technical teams room to move without losing control, and maturing a feature through iteration grounded in real learning.
⚠️All product names, figures, and metrics in this portfolio are fictional or illustrative and created for demonstration. The case studies show how I think about product — problem framing, state machines, governance, research — without containing confidential information from any real project ⚠️
selfservice | governance | RBAC
provenance | sync | migration
I wanted branches to design their own forms without waiting on an engineering release — but without losing governance. So I designed the builder with review-approval, access control per-role and per-branch, and publishing.
THE PROBLEM
Every form was hardcoded. Adding a single form meant going through the engineering cycle — slow, expensive, and unscalable across hundreds of branches.
KEY DECISIONS
Governance from the start, not later · published forms are immutable · reorder with buttons first, drag-drop deferred.
I shipped this feature, then matured it based on how people actually used it. From re-typing data by hand, to syncing automatically from the source — with provenance and safe migration.
ITERATION
In v1, documents could be created — but people had to re-type data that already existed. In v2, the data is pulled automatically, with the right rules.
KEY DECISION
Dedicated columns, not JSON, so it’s queryable · a snapshot that preserves manual curation across re-syncs · a source of truth I marked explicitly for engineering.
SAFE MIGRATION
Backfill first, then enforce the constraint · dry-run in staging · log every failed record for manual review.
At first glance, the system looked fine. Teams kept processing transactions, invoices kept going out. But once I looked closer, a different story emerged: every module managed its own transaction identity, billing was created manually and easily lost, and cancelling a payment meant deleting data. Four problems that seemed unrelated were, in reality, rooted in the same thing.
As I mapped the complaints, four patterns kept recurring — and every one of them chipped away at trust in the system.
No central identity. Teams couldn’t refer to “the same transaction” consistently; coordination happened manually and was prone to mis-linking.
Billing not tied to transactions. Invoices were created by hand, easily duplicated or lost, and hard to reconcile.
Multi-source payment unsupported. Real scenarios — a deposit, then credit, then final settlement — didn’t fit in a single account.
Unsafe cancellation. Cancelling meant deleting data, and the audit trail disappeared with it.
Foundation first, features later
I separated transaction identity into its own release, before building billing on top. This delayed user-visible features — but prevented far more expensive technical debt down the line. I made the trade-off deliberately and communicated it to stakeholders.
Auto-generate, not manual entry
Document numbers and billing accounts are system-generated and can’t be overridden. I removed a source of human error, at the cost of a flexibility that — once I looked into it — turned out not to be needed.
Reversal, not delete
Cancelling creates a new correction transaction rather than removing the old one. It’s harder to implement, but it’s non-negotiable if I want the system to be financially trustworthy.
Explicit payment priority
I set the order in which the balance is reduced — deposit first, then credit — so the calculation stays deterministic and auditable, not dependent on interpretation.
Rather than patching each issue one by one, I wanted a foundation that closed all four at once.
One transaction identity, consistent across every module.
A billing account generated automatically for each order, with no manual step.
Staged payment from multiple sources within a single account.
Cancellation with dual authorization and a permanent audit trail.
THE PROBLEM
KEY DECISION AND TRADE_OFF
WHAT I SET OUT TO DO
I build the foundations systems rely on.
product and development
Five things that always show up.
Whether I’m working on billing, transaction identity, or user research, my approach tends to return to the same five things. This is the thread that best describes how I think.
how i work
core product
supporting modules
v1 re-typing —>
v2 auto sync
Systems thinking
Strict state machines
Governance & RBAC
Scope discipline
Safe releases
Three trust failures, one shared consequence: members and studios stop relying on the platform.
I model the transaction lifecycle explicitly, so system behaviour stays predictable and auditable.
Access per-role and per-branch, review-approval flows, and dual authorization for anything sensitive.
I’m firm about what ships and what doesn’t. Complexity is deferred deliberately, not forgotten.
Risk registers, phased migration strategy, and concurrency handling — so change doesn’t break what already works.
01
02
03
04
05
Order and billing engine
Two other stories: governance and iteration.
Custom Document Builder
Document Generation
One order as the source of truth.
~40%
try it live
try it live
need sample of my PRD document? click below~
ps: need my real PRD document? please contact me through my email —> amalliayova.ardina@gmail.com
~90%
0
1:1
reduction in cashier reconciliation time
drop in lost/duplicate billing incidents
of cases were early-morning classes
billing account per order, automatic
Parent Order as the source of truth; every document must link to one Order ID.
Automatic numbering per document, with a daily sequence per branch and atomic increment so numbers never collide.
State machine: OPEN → PAID (soft lock) → CLOSED (hard lock); reversal PAID → OPEN only while no closing exists.
Dual authorization for reversal: requester and approver are separate, a reason is required, and the audit trail is permanent.
Because this touches money, I mapped the failure modes up front rather than waiting for them to happen.
Two operators processing the same bill → locked with a “processing” status + session control.
Double reversal on one payment → a payment can only be reversed once.
Number collision under high traffic → atomic increment at the database level.
Duplicate orders from a race condition → unique constraint + database transaction.
THE SOLUTION
RISK I ANTICIPATED
~2 weeks → ~1 day · time for a new form to go live
~60% · reduction in document creation time
Most of my work isn’t about adding new features. When I look closely at a product, the problems that surface most often live in a layer people rarely see: transaction identity, billing, and data governance. That’s where I work — building a backbone teams and branches can actually trust.