Bean & Bark: the model becomes the code
You've modelled the store, questioned it, operated it safely, and declared it once as annotated C#. The last step is to ship — and here's the payoff Part 2 was building toward: the model from the last chapter becomes the code your app runs. You'll add referrals to Bean & Bark, and you'll never write the data layer, the schema, or the constraint twice.
- Generate a data-access method from your model — the raw AWS SDK form, or the terse Kanject repository form
- Ship a real feature with a new marker (a unique code) and an atomic transaction (dual credit)
- Close the loop — watch the studio read exactly what the app just wrote
The model was the code all along
That one annotated model has been the source of truth the whole time — the schema DynoStudio reads, the rulebook the table enforces. Now it's the source of your code too. Add [Unique("ReferralCode")] to Customer, hit codegen on the lookup, and the studio emits ready C# — two ways. Take the raw AWS SDK form when you want zero dependencies and can carry the marker's two-step yourself:
// find a customer by referral code — the marker's two-step, by handvar marker = await ddb.GetItemAsync(new GetItemRequest { TableName = "BeanAndBark", Key = { ["pk"] = new AttributeValue($"$$Unique#ReferralCode#{code}"), ["sk"] = new AttributeValue("ReservedData"), },});if (!marker.Item.TryGetValue("RefHashKey", out var refPk)) return null;// the marker row already holds the target's full key — you never guess its skvar found = await ddb.GetItemAsync(new GetItemRequest { TableName = "BeanAndBark", Key = { ["pk"] = refPk, ["sk"] = marker.Item["RefRangeKey"] },}); …or take the Kanject repository form, where the marker you declared does exactly that work for you:
// [Unique("ReferralCode")] generated this — the code IS the argument, the two reads hiddenCustomer? referrer = await customers.FindCustomerByReferralCodeAsync(code); Sixteen lines become one call — and it isn't a leaky wrapper hiding something you should worry about. It is the [Unique] marker from the last chapter, generating its own reserved-row lookup: the code you pass is exactly the value the marker keys on. Same model, less to get wrong.
Ship it — atomically
Redeeming a referral touches two customers: credit the referrer, credit the new one. Either both happen or neither does — anything else means someone got $5 the other didn't. That's a transaction. Your endpoint calls the generated repository; DynoStudio previews it executing as a native TransactWriteItems, all-or-nothing:
-- redeem: credit both accounts, all-or-nothingBEGIN TRANSACTION; UPDATE "BeanAndBark" SET CreditCents = CreditCents + 500 WHERE pk = 'CUSTOMER#c-014' AND sk = 'PROFILE'; -- the referrer UPDATE "BeanAndBark" SET CreditCents = CreditCents + 500 WHERE pk = 'CUSTOMER#c-207' AND sk = 'PROFILE'; -- the new customerCOMMIT; - Codegen turns an access pattern into ready C# — the raw AWS SDK form, or the terse Kanject repository form that uses the markers you declared.
- A feature ships with a marker (a unique referral code) and a transaction (both accounts credited, or neither).
- The studio reads what the app writes: model once, and the schema, the constraints, and the code all agree — no drift, no second definition.
Customer model from the last chapter, so it both generates a lookup and can never collide.[Unique(...)] marker you used for Email — one attribute, one property.Show solution
[Unique("ReferralCode")] on a ReferralCode property generates FindCustomerByReferralCodeAsync and guarantees no two customers share a code — a reserved $$Unique#ReferralCode#… row makes a duplicate impossible.[Unique("ReferralCode")]public string ReferralCode { get; set; } UPDATE ... SET CreditCents = CreditCents + 500 statements (each keyed to a full primary key) in BEGIN TRANSACTION; … COMMIT;.Show solution
UPDATEs inside BEGIN TRANSACTION; … COMMIT; execute as one TransactWriteItems — all-or-nothing, so a referrer is never credited without the new customer.BEGIN TRANSACTION; UPDATE "BeanAndBark" SET CreditCents = CreditCents + 500 WHERE pk = 'CUSTOMER#c-014' AND sk = 'PROFILE'; UPDATE "BeanAndBark" SET CreditCents = CreditCents + 500 WHERE pk = 'CUSTOMER#c-207' AND sk = 'PROFILE';COMMIT;