Steve Trucking at Scale, What I Would Architect
यह कंटेंट अभी तक आपकी भाषा में उपलब्ध नहीं है।
The question this checkpoint answers: Can you put Part 2 together on a real scenario?
Try the challenge first. This is my walkthrough of Checkpoint 2’s challenge. If you haven’t taken your own design to year five yet, do that before you read on. The value is in comparing your reasoning with mine, not in reading the answer.
This is “What I Would Architect” again: a possible viable solution, not the answer, with the trade-offs named and my positions taken. At Checkpoint 1 we set the bones: Field Service as the delivery core, one custom Manifest__c, the partner’s key on the Work Order, the Recipient as fields on the delivery, and photos, GPS and status history kept off core. I’m keeping all of it. Part 2’s job was to test it: volume, retrieval, integration, migration, transactions and security. So the question here is whether those bones survive year five, and what has to be added so they do.
Start With the Numbers, at Year Five
Section titled “Start With the Numbers, at Year Five”The requirement says three times today’s volume within five years (O1). Chapter 7 did the math (When Volume Changes Everything): 1.0 million deliveries in year one, then 1.3, 1.69, about 2.2 and about 2.86 million in year five. Keep all five years and the org holds about 9 million Work Orders, about 14.5 million line items, and, if we kept them, about 72 million status changes.
Now the data we decided not to put in core. About four photos a delivery is over 11 million photos a year by year five. GPS is 200,000 readings a day today, about 73 million a year; if the fleet grows with the deliveries, it’s past 200 million a year by year five. Cases grow too: 180,000 a year today, about half a million by year five.
Put those on chapter 7’s ruler. A little drag at a million records in an object; list views taking seconds heading toward 50 million; past 100 million, ask whether the records belong here at all. Nine million Work Orders kept forever is the slow, steady kind of problem, the one nobody notices until year four. GPS and photos are the kind you never put in core in the first place. That’s Steve’s Number of Zeros: the zeros already told us most of this design before we drew a box.
Decide How a Delivery Leaves
Section titled “Decide How a Delivery Leaves”Chapter 7 gave us the rule: design the exit when you design the entrance. So the first decision is how long a completed delivery stays in the org.
The floor is the claims window. Retail Partners raise damage and install claims, about 15,000 a year today, and chapter 10 set the claim window at 60 days: “the business’s number, not ours.” Anything a claim can still touch stays in the org, with its case, its photos’ links and its credit. But 60 days is a floor, not a recommendation. Coordinators look back at last month’s exceptions. Retail Partners see on-time and damage rates by DC and by day (RP1), and they’ll want to compare this month with the same month last year.
In my professional opinion, a completed delivery stays in the org for 13 months, then leaves. At year five that’s roughly 3 million Work Orders in the org instead of 9 million, and the number stops climbing: it moves with the business, not with time. Leadership’s five-year reporting (RP2) comes from the warehouse, where the status history already is.
Where does it go? Snowflake, by the partner key. That’s the same place RouteDesk’s 4.8 million older deliveries go in chapter 10, and the same place the status history already lives. One archive, one key, one place to look. Chapter 7 also showed big objects and Salesforce’s own archive product; either could work, but Steve Trucking already runs Snowflake, the history is already there, and a late claim or an audit question is answered by the partner key in one query.
And the security has to survive the move, the question chapter 7 asked. In Snowflake, a partner’s archived deliveries are still that partner’s: whatever reads the archive for a partner reads only that partner’s rows. And no agent reads the archive. Chapter 7 said that’s a significant decision and the business’s to make; my recommendation is no, because no agent’s job here needs five-year-old deliveries.
Personal data leaves earlier, and not all of it goes. When a delivery leaves the org, the archive keeps what history needs: the partner key, the Retail Partner Customer ID, the dates, the items, the status trail, the postal code. It doesn’t keep the Recipient’s name, phone, email or delivery notes. The gate code doesn’t even wait for the archive: its own small record is deleted when the delivery is completed, because no job after that needs it. That’s module 3’s minimization is a security control too, turned into a lifecycle.
Find the Hot Spots Before They’re Hot
Section titled “Find the Hot Spots Before They’re Hot”Three places concentrate work at Steve Trucking, and Part 2 found all three.
- The partner account (Hot Spots: Ownership, Parent and Lookup Skew). If Redrock is 40% of the business, five years would put about 3.6 million Work Orders under one Account. I keep the relationship, because it’s real, and add a child account per DC under each partner: nine today, each one a real place the business recognizes. With the 13-month window, the active Work Orders per DC account stay in the low hundreds of thousands. Scale fixes still have to preserve meaning, and a DC is a meaning.
- The owner. The integration creates the deliveries, but that doesn’t mean it should own them. In this design ownership doesn’t drive anyone’s access (the sharing below doesn’t use it), so the Work Orders get a dedicated owner with no role, chapter 7’s isolated high-volume owner, not the integration user.
- The Manifest at four o’clock (Designing Out Lock Contention). Chapter 11 found the deadlock: every delivered stop recounting its Manifest inside the save. The fix stays: keep the Manifest, stop recounting it inside every save, and give each Manifest its own line. The counts arrive through a platform event, after the save. And
Manifest__cis a lookup from the Work Order, not a master-detail, with partner access through sharing (chapter 7), so the Manifest never becomes every delivery’s lock owner.
The Nine Contracts
Section titled “The Nine Contracts”Chapter 9 numbered the important arrows on the landscape, C1 to C9, and wrote C1, Redrock’s manifests, line by line (The Integration Data Contract). It deliberately left the other eight for this checkpoint. Here they are, at the level an architect signs off: who starts it, how fresh it must be, the key, and the line most teams leave out, who proves it arrived. Chapter 9’s rule decides that line every time: the client owns the conversation. Whoever knows what should arrive proves that it did.
| Contract | Starts it | How fresh | Key | Who proves it arrived | |
|---|---|---|---|---|---|
| C1 | Redrock’s manifests in (REST) | Redrock | A revision on the Work Order within 15 minutes | Partner_Delivery_Key__c | Redrock, from the per-record results: sent equals accepted plus rejected |
| C2 | Status to Redrock (webhook) | Salesforce, through the integration layer | Seconds | The same key | Salesforce: the return receipt, and a sweep that sends again what has none after three hours |
| C3 | Keystone’s manifests in (SFTP file) | Keystone drops the file; the integration layer picks it up | Loaded well before routes are finalized the evening before | The same key | Keystone, from an acknowledgment file we send back: rows received, accepted, rejected with reasons |
| C4 | Status to Keystone (nightly file) | The integration layer | Nightly | The same key | Salesforce: a file isn’t proof; Keystone’s pickup or acknowledgment is, and a missing one is chased by morning |
| C5 | Brightwave’s manifests in (EDI) | Brightwave, through its EDI network | Before routing, like C3 | The same key | Brightwave, from the acknowledgment we return through the network |
| C6 | Status to Brightwave (EDI) | The integration layer | As Brightwave’s agreement sets | The same key | Salesforce, from Brightwave’s acknowledgment |
| C7 | Status history to Snowflake | The integration layer subscribes | Near real time, or hourly | Work Order | The integration layer: the day’s status changes published equal the rows landed |
| C8 | The truck’s latest position from FleetLink | Either side (chapter 9 shows both) | A few minutes | Truck | Freshness, not every reading: a position older than the contract allows shows as stale on the dispatcher’s map |
| C9 | Delivery counts to the finance ERP | The integration layer | Daily | Partner and day | The integration layer: the ERP’s totals match the day’s completed deliveries, installs and haul-aways per partner |
Two things I want you to notice. First, the key column is one value, Partner_Delivery_Key__c, for six of the nine. That’s Checkpoint 1’s decision paying off: one unique External ID with the partner in the value, so Keystone’s file, Redrock’s API and Brightwave’s EDI all upsert the same way, and a resent or revised manifest updates instead of duplicating. A fourth partner is a new value, not a new field. Second, the proof column changes direction with the arrow. For manifests in, the partner knows what it sent, so it proves it; our job is to give it the results it needs. For status out, we know what should arrive, so we prove it.
And Manifest__c is where the manifests’ proof lives in the org. Keystone sent 1,842 deliveries for Thursday at the Dallas DC; we received 1,842; 1,790 new, 47 revisions, 5 rejected with reasons and sent back. That’s a manifest I can operate. “The integration ran green” isn’t.
Revisions after routing (R4) are where integration meets the business. The upsert applies the partner’s change, because the partner owns the items, the address and the date. But Salesforce owns the appointment, the crew and the route (chapter 9: bidirectional movement doesn’t require bidirectional authority). So a change to an already-routed delivery is applied and flagged, and the coordinator sees the affected route in minutes. A new address on a loaded truck isn’t a field update. It’s a decision for dispatch.
Retire RouteDesk Without Moving It In
Section titled “Retire RouteDesk Without Moving It In”Chapter 10 made the RouteDesk decisions (Migration Is a Quality Project First), and they hold here: migrate, archive, or discard according to policy. The deliveries not yet made, about 6,400, come in, because they still have to happen. So do the roughly 190,000 inside the 60-day claim window, because a claim can still reach them. The other 4.8 million go to Snowflake by the partner key, the same archive our own completed deliveries will join after 13 months. Route plans and coordinators’ drafts are discarded by policy.
Then prove it: counts, totals, spot checks and aggregate reports, such as deliveries by DC by week in RouteDesk against the same in Salesforce and Snowflake. On Day 0, authority moves, and RouteDesk goes read-only. RouteDesk retires without Salesforce becoming its retirement home.
Credits, Safe to Retry
Section titled “Credits, Safe to Retry”One transaction from chapter 11 belongs in every checkpoint from now on: the damage credit that went out twice. A $180 credit, a timeout, a retry, and $360 paid. The fix is in the design, not in the hope that timeouts won’t happen: the claim number is the idempotency key, so the same claim can’t produce two credits, whoever retries (Safe to Retry). If the client owns the retry, the architecture must make the retry safe. That matters even more now that an agent can call the credit action.
Who Sees What
Section titled “Who Sees What”Now the access model. Module 1’s point is the reason it comes last: most of it was decided in the model. Every Work Order carries its Retail Partner and its DC account; the Recipient lives on the delivery; the gate code lives on its own record. Here’s each consumer, what it gets, and what enforces it.
Retail Partners: the hard boundary (S2, R3). Work Orders are private. Partner users sit on Customer Community Plus or Partner Community, Checkpoint 1’s license decision. For the partner-wide view, module 2’s design holds: a group per partner and one criteria-based rule per partner, three rules today.
For the DC managers, I don’t want a rule per DC. Module 2 counted that series: nine today, one more for every DC the business wins, all inside the limit of 50 criteria-based rules per object. So I use the structure the model already has: a sharing set.
A sharing set “grants site users access to any record associated with an account or contact that matches the user’s account or contact” (Salesforce Help, Create a Sharing Set for Experience Cloud Site Users (opens in a new tab), checked 2026-10-28). The linkage is an access mapping: a field on the user on one side, a field on the target object on the other, both pointing to an account or a contact. For Steve Trucking, each DC manager is a contact under their DC’s account, and each Work Order’s account is that DC account. Map the user’s Contact.Account to the Work Order’s Account, read only, and a DC manager sees exactly their own DC’s deliveries. Work Order is on Salesforce’s list of objects a sharing set can share, and so is Case, so the claims can follow the same linkage. And sharing sets aren’t only for the cheap seats: Salesforce lists Customer Community Plus and Partner Community among the licenses that support them (Metadata API Developer Guide, SharingSet (opens in a new tab), API version 68.0, checked 2026-10-28). One sharing set, and every new DC is a new account, not a new rule. The child account we added for skew now carries the security too. That’s the data model and the security model designed together.
But sharing sets are a very focused tool, so check the fit before you rely on one:
- One sharing set per profile. Salesforce says it plainly: “You can have one sharing set per profile only.” Inside that set, each object gets its own access mapping. So the DC managers get their own profile, and everything that profile needs from a sharing set, the Work Orders and the claims, goes into that one set. Plan the profiles with the sharing sets, or a second need on the same profile has nowhere to go.
- It doesn’t roll up. “Record access granted to users via a sharing set isn’t extended to their superiors in the role hierarchy.” A partner-wide manager above the DC managers doesn’t inherit their deliveries. That’s why the partner-wide view stays on the three criteria-based rules.
- The object has to be private. Objects with an org-wide default of Public Read/Write aren’t available. Work Orders are private, which was module 2’s starting point anyway.
- The linkage has to be right on every record. The access is only as good as the Work Order’s account. If an integration writes the partner’s parent account instead of the DC account, the DC manager sees nothing. If it writes the wrong DC, the wrong DC manager sees it. That’s a contract line for C1, C3 and C5: the DC account is set from the manifest’s DC, and it’s checked.
Test knowledge. Know that sharing sets grant portal users access to records whose account or contact matches the user’s, through an access mapping per object; that they’re available to Customer Community Plus and Partner Community users as well as Customer Community; that you get one sharing set per profile; and that sharing-set access isn’t extended to superiors in the role hierarchy.
Coordinators and customer care. Coordinators work inside one partner’s DC. They see that DC’s deliveries for the day’s work, through the same DC structure. Customer care sees across partners, because Recipients call Steve Trucking, but through the console, with the Recipient’s phone the one Confidential field they search by.
Crews: their stops, on the day (S4). The crew’s access follows the assignment Field Service already has: the Service Appointment and its assigned resources. And crews work offline (R11), so what’s on the phone matters as much as what’s in the org. The Field Service app starts by loading “all Service Appointments for the default list view” (Salesforce Help, Salesforce Field Service app for iOS and Android performance considerations (opens in a new tab), published July 14, 2026, checked 2026-10-28). So the default list view is the crew’s own appointments scheduled today, and only today’s stops go onto the phone.
Don’t expect the cache setting to clean up afterwards. Its Record Data Cache Time “controls how long offline data is considered valid for. When this time expires, the app will check for updates.” That’s freshness, not deletion.
Then the gate code. Module 1 offered two ways to protect it: a controlled door, or moving it to its own record. The door is an online check, and a crew standing at a gate often has no signal. So here I move it. The gate code gets its own small record, a lookup child of the Work Order with its own private access, shared only with the crew assigned to that stop, for that day. It goes onto the phone with the stop.
This is how I’d treat a true secret that’s given to us for a short time:
- No wider access. We aren’t taking an existing record and trying to expose more of it, then worrying about what else that opens. Only this one record is shared, with only these people, so there’s no lateral effect on any other field.
- Easy to remove. When the stop is completed, the record is deleted, and that piece of confidential data is gone from the org, and it should leave the phone at the next sync. Salesforce’s documentation doesn’t say exactly when a deleted record leaves the device, so prove it on a real phone before go-live, the same way you’d prove any other security control. We can make it appear, and we can make it disappear.
The partner integrations. Each partner’s integration has its own user (module 1: the Salesforce Integration user license with the Minimum Access - API Only Integrations profile), with write access only to the fields that partner owns: the items, the address, the delivery date. A test payload that tries to change the crew is refused. Permission says can; architecture says should.
Recipients: one delivery, no login (S3). The text message carries a link with a long, random, single-purpose token. The org stores only a hash of it, with an expiry, against one delivery, and it stops working seven days after the delivery, long enough for the photos and the survey (R7). The tracking page doesn’t get access to Work Orders at all, so there’s no guest-user sharing rule to write, which matters because guest user rules count in the same 50 as criteria-based rules (module 2). Instead, the page calls one controlled action: given a valid token, return this delivery’s window, status, the truck’s latest position near the end of the route, and the photos after delivery (R5–R7). Change one character of the link and it returns nothing. After the expiry, the same.
The agents (R8). Module 4’s three agents, each with one job. The Recipient’s agent works from the same token context as the page, reaches one delivery through an action, and can move the window within the partner’s rules. The care team’s agent runs as the care agent and summarizes. The finance agent checks eligibility and issues an approved, idempotent damage credit, with a person approving anything over $1,000 in a Flow checkpoint. None of them reads the archive. And before go-live, we try to break each one: discover, derive, infer, act.
Classify What’s There
Section titled “Classify What’s There”The protection matrix from module 3, applied:
- Restricted: the gate code. On its own record, shared only with the assigned crew for the day; encrypted with Shield, probabilistic, because nobody filters on it; deleted when the delivery is done.
- Confidential: the Recipient’s name, phone, email, address and delivery notes; delivery photos (S5); each partner’s pricing and volumes (S2). The phone is the one field customer care searches by, so if it’s encrypted, it’s the one case for deterministic encryption: probabilistic by default; deterministic only where exact-match filtering is essential. Masked outside production.
- Internal: Work Orders, routes, manifests, crews. Partners see their own through the portal.
- Public: almost nothing. The tracking page shows one delivery to the person holding its link, and that isn’t public; it’s a token.
The Option I Didn’t Choose
Section titled “The Option I Didn’t Choose”The obvious alternative is to keep everything in Salesforce because the deliveries are there: every status change, every photo, every GPS reading, all eight years of RouteDesk, every completed delivery forever. Then give the integrations and the agents broad access to it, and write a sharing rule for every DC.
It’s attractive: one place. But one place isn’t automatically good architecture. It’s 9 million Work Orders and climbing, hundreds of millions of rows that were never business records, a file-storage bill, more personal data in more places for longer, a sharing-rule series heading for the limit, and an archiving project we can already predict today. I don’t choose that design.
In My Professional Opinion
Section titled “In My Professional Opinion”The requirement is: run Steve Trucking at three times today’s volume, with three partners integrated three ways, RouteDesk retired, and partners, crews, Recipients, applications and agents each seeing only what their job needs.
My solution is: keep Salesforce the lean operational core, with completed deliveries leaving after 13 months for one archive in Snowflake by the partner key; a child account per DC that spreads the skew and carries the DC boundary; nine written contracts with one key and a named prover for every arrow; RouteDesk migrated, archived or discarded by policy and proved; idempotent credits; and access designed around the job: sharing sets for DCs, the assignment and a temporary gate-code record for crews, a token for Recipients, narrow users for integrations and agents.
The reason is: each piece of data gets a home sized for its volume and an exit designed on day one, and each consumer gets a boundary the model can enforce.
The option I didn’t choose was one org holding everything forever, opened up with rules and broad users.
In my professional opinion, the strongest architecture isn’t the one that puts the most in Salesforce. It’s the one where every record has a reason to be there, a way to leave, and a boundary around who can reach it.
What’s Still Open
Section titled “What’s Still Open”Part 2 tested the bones, and they held, with a lifecycle, a DC account and nine contracts added. Part 3 asks what changes when the same data has to serve analytics and AI: a view of the archive from inside Salesforce instead of a copy, Data 360, and grounding the agents. And Steve Trucking will change again. Keep this design; you’ll revisit it.
What an Architect Decides Here
Section titled “What an Architect Decides Here”- The year-five numbers for every large object, and which never enter the core.
- How long a completed record stays, where it goes, how it’s found, and how its security and its personal data are handled on the way out.
- Which parents, owners and shared records will concentrate work, and the model change that prevents it.
- A contract for every important arrow, with the key and who proves it arrived.
- What the old system migrates, archives and discards, and the proof.
- Each consumer’s boundary, and the mechanism the model gives it: sharing rules, sharing sets, a record of its own, a token, a narrow user.
Explore
Section titled “Explore”- The Steve Trucking brief and challenges (D2, D3, D4, D7; S2–S5).
- Part 2’s Steve Trucking decisions: When Volume Changes Everything, Hot Spots: Ownership, Parent and Lookup Skew, The Integration Data Contract, Migration Is a Quality Project First, Designing Out Lock Contention, Safe to Retry.
- Salesforce Help: Create a Sharing Set for Experience Cloud Site Users (opens in a new tab), checked 2026-11-01.
- Salesforce Help: Salesforce Field Service app for iOS and Android performance considerations (opens in a new tab), published July 14, 2026, checked 2026-11-01.
- Salesforce Developers, Metadata API Developer Guide: SharingSet (opens in a new tab), API version 68.0, checked 2026-11-01.
