Перейти к содержимому

Как бы я это спроектировал

Также доступно на 28 языках

English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Nederlands · العربية · עברית · Українська · हिन्दी · Svenska · Dansk · Norsk bokmål · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

A row of plain white delivery trucks ready at the loading doors at first light, a clipboard on the front of the nearest one.
Изображение создано с помощью ИИ

Модуль 6 из 6 главы Мастер-данные и идентичность, глава 6 курса Data Architect, и завершение части 1. Назад: Когда полномочия разделены · Далее: часть 2 начинается с главы Проектирование для масштаба (coming soon)

Вопрос, на который отвечает эта контрольная точка: можете ли вы собрать часть 1 воедино на реальном сценарии?

Сначала попробуйте выполнить задание. Это мой разбор задания контрольной точки 1. Если вы еще не нарисовали свой дизайн, сделайте это, прежде чем читать дальше. Ценность — в сравнении ваших рассуждений с моими, а не в чтении ответа.

Это «Как бы я это спроектировал»: одно из возможных жизнеспособных решений, а не единственный ответ, с названными компромиссами и моими позициями. Мы еще не разбирали большие объемы данных, проектирование запросов, шаблоны интеграции, миграцию и транзакции, и это намеренно: архитектура развивается по мере того, как вы узнаете больше. Но части 1 достаточно, чтобы заложить скелет.

Из описания: около 3 300 доставок в рабочий день, миллион в год, рост 30 % в год. Около 1,6 позиции на доставку (1,6 млн в год); около восьми смен статуса на доставку (8 млн в год); четыре-пять миллионов фотографий в год; около 200 000 GPS-отметок в день; около 180 000 обращений в год; три розничных партнера, отправляющих манифесты тремя разными способами; девять распределительных центров; 330 грузовиков с бригадами из двух человек. И у Steve Trucking уже работает один org Salesforce с Service Cloud, Field Service и партнерским порталом. Посчитайте нули, прежде чем рисовать хоть один прямоугольник. Ниже они решат несколько вопросов.

Ядро доставок: смотрите на корабль-носитель

Заголовок раздела «Ядро доставок: смотрите на корабль-носитель »

Доставки — это сердце всего, а диспетчеризацию уже выполняет Field Service. Поэтому я начинаю со стандартной модели Field Service, как это сделал фрагмент в главе 3:

Бизнес-понятиеОбъект SalesforceПочему
Розничный партнер (Retail Partner)Account (тип записи Retail Partner)Компания, с которой у Steve Trucking договор; несет договоры, обращения и доступ к порталу
Сотрудники партнера (менеджеры DC, персонал магазинов)ContactПользователи портала должны быть контактами
Одна доставка: один получатель, один адрес, один заказ партнера, один деньWork OrderЕдиница работы в Field Service; к ней привязаны планирование, мобильное приложение и сервисные отчеты
Каждый товар или услуга: холодильник, установка, вывоз старогоWork Order Line ItemДелит работу, управляет чек-листами и выставлением счетов
Вид остановки: только доставка, с установкой, с вывозомWork TypeЗадает длительность, навыки и чек-лист установки
Запланированный визит и его окноService AppointmentТо, что планирует Field Service и показывает приложение бригады
Бригады и грузовики; зоны диспетчеризации DCService Resource, Service Crew, Service TerritoryField Service планирует бригаду как один ресурс
Вопросы получателей, претензии партнеровCaseКонсоль обслуживания, права на обслуживание (entitlements), email-to-case
Список партнера на вторник для DC в ФиниксеManifest__c (пользовательский)Ничто стандартное не представляет единицу приема, сверки и повторной обработки

Все остальное остается стандартным. Сопротивление новым пользовательским объектам — сознательное: в главе 1 был вопрос, когда архитектору стоит сопротивляться еще одному такому объекту, и здесь ответ — «почти всегда». Строка заказа партнера, например, — это не новый объект. Это Work Order, идентифицируемый по ссылке партнера.

Контрольная точка 1: ядро доставки Физическое ядро контрольной точки 1 для Steve Trucking. В ядре: розничный партнер, организация с типом записи, отправляет манифесты, единственный пользовательский объект, и каждая доставка для одного партнера. Манифест перечисляет доставки. Доставка — это рабочий заказ (Work Order) с получателем в виде полей; она планируется как встречи, сервисные встречи (Service Appointment), содержит позиции доставки, позиции рабочего заказа (Work Order Line Item), каждую из которых описывает вид остановки, тип работы (Work Type). Бригада, сервисная бригада (Service Crew), назначается на встречи и работает в зоне диспетчеризации DC, сервисной территории (Service Territory). Запрос или претензия, обращение (Case), может касаться доставок. Вне ядра: GPS-отметки бригады идут в хранилище данных, доставка ссылается на фото доставок в хранилище фото, а каждая встреча публикует свою историю статусов как события в хранилище данных. Внизу: смотрите на корабль-носитель: Field Service — это ядро доставки. В ЯДРЕ ВНЕ ЯДРА отправляет для перечисляет касается планируется как содержит описывает бригады работают в назначается на отмечает ссылается на публикует Розничный партнер Account · тип записи Манифест Manifest__c · пользовательский Запрос или претензия Case Доставка WorkOrder · Поля получателя Позиция доставки WorkOrderLineItem Встреча ServiceAppointment Вид остановки WorkType Зона диспетчеризации DC ServiceTerritory Бригада ServiceCrew История статусов события, хранилище Фото доставок хранилище фото, по ссылке GPS-отметки хранилище, по ссылке Смотрите на корабль-носитель: Field Service — это ядро доставки. ровно один ноль или один один или много ноль или много lookup © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Она вырастает из финальной диаграммы главы 3 (Спроектируйте физическую модель Salesforce): те же объекты на тех же местах, плюс бригада, зона диспетчеризации, обращение и то, что контрольная точка 1 держит вне ядра.

Ключ, который сопоставляет заказ партнера с доставкой

Заголовок раздела «Ключ, который сопоставляет заказ партнера с доставкой »

Каждая строка манифеста становится одним Work Order, связанным со своим манифестом. Ключ — это вопрос, на который я больше всего хочу получить ответ: как мы узнаем, что эта строка от партнера — это та самая доставка? Мой ответ: External ID на Work Order, составленный из розничного партнера и собственной ссылки партнера на заказ и доставку (что-то вроде KEYSTONE-PHX-8843119-1), с отметкой unique (уникальный). Одно поле на источник, один к одному. Это идентификатор партнера, а не наш: «несколько идентификаторов для одной сущности» из главы 2 и «партнер владеет ссылкой на свой заказ» из модуля 1.

Почему это важно: манифесты приходят за один-два дня и пересматриваются в день доставки. С таким ключом каждый повторно отправленный или пересмотренный манифест выполняет upsert, а не создает дубликаты. Пересмотр обновляет Work Order, поле фиксирует это, а изменение уже распределенной по маршруту доставки оповещает координатора: изменение партнера применяется, но помечается, пока диспетчер его не подтвердит. Это же меняется и по сравнению с картиной из главы 4. Сегодня каждый манифест попадает в RouteDesk, а координаторы вручную перенабирают маршруты в Salesforce и выполненные остановки обратно. В этом дизайне манифесты приходят прямо в Salesforce через upsert по ключу партнера; RouteDesk выводится из эксплуатации, и перенабор заканчивается. Три входящих формата спроектирует глава об интеграции. Решение о данных — это ключ.

Получатель: персональная учетная запись, контакт или ни то ни другое?

Заголовок раздела «Получатель: персональная учетная запись, контакт или ни то ни другое? »

Это самое интересное решение о данных в части 1, поэтому вот варианты, а затем мой выбор.

Вариант A: персональные учетные записи (Person Account). Каждый получатель становится персональной учетной записью, связанной с каждой доставкой. За: стандартно, естественно работает с Service Cloud, сообщениями и консолью, узнает повторных получателей. Против: около миллиона новых получателей в год, каждый — персональная учетная запись, занимающая примерно вдвое больше места, чем бизнес-организация (Estimated Record Size by Object Type (opens in a new tab)), так что за два года это один из крупнейших объектов в org. И получатели — не клиенты Steve Trucking. Это клиенты каждого розничного партнера, и Steve Trucking никогда не должен смешивать клиента одного партнера с клиентом другого (S2).

Вариант B: контакты под организацией розничного партнера. Против: миллион контактов под тремя-четырьмя организациями — это перекос данных «родитель — потомок» (parent-child skew) в огромном масштабе, далеко за пределами рекомендации Salesforce — около 10 000 дочерних записей на родителя (Considerations for Object Relationships (opens in a new tab); Parent-Child Data Skew (opens in a new tab)). Этот вариант нужно показать — и отвергнуть.

Вариант C: получатель живет в доставке. Имя, телефон, адрес электронной почты, адрес и примечания к доставке получателя — это поля на Work Order (поля адреса там уже стандартные), взятые из манифеста. За: никакого нового большого объекта; данные живут ровно столько, сколько они нужны доставке; удаление происходит по каждой доставке, по графику партнера; а изоляция партнеров достается бесплатно, потому что каждая доставка принадлежит одному партнеру. Против: повторный получатель не распознается как тот же человек.

Вот баланс, который нужно найти. Понадобится ли когда-нибудь распознавать несколько доставок как доставки одному и тому же человеку по одному и тому же адресу? Давать этому человеку вход в систему? Это граница между получателем, которому нужна собственная запись, и сведениями о получателе, которые просто являются данными о доставке. И есть средний путь. Храните собственный ID клиента розничного партнера как поле на доставке — Retail Partner Customer ID. Он не создает запись получателя, но связывает доставки, которые партнер отправляет для одного и того же клиента, — а это начало более единого клиентского опыта, — и ведет прямо обратно в систему розничного партнера, где этот клиент на самом деле живет. Это их идентификатор, поэтому он что-то значит только вместе с партнером: клиент 4417 одного партнера не имеет ничего общего с клиентом 4417 другого.

По моему профессиональному мнению, правильный выбор — вариант C. То, что повторный получатель не распознается, приемлемо и даже желательно: у Steve Trucking нет отношений с этими людьми за пределами доставки. Это снова модуль 1: получатель — клиент партнера, и партнер — источник полномочий в том, кто этот человек. И это глава 5: персональные данные, которые оседают в одном месте и привязаны к одной доставке, гораздо легче защищать, хранить и удалять. И это выдерживает проверку нормальными формами из главы 2: сведения о получателе связаны с доставкой один к одному, поэтому им место в ней. Отдельная дочерняя запись получателя сэкономила бы несколько повторяющихся значений ценой еще одного объекта, еще одной связи и накладных расходов на нее, а сэкономить больше она могла бы, только если считать одного и того же человека единым для разных розничных партнеров, чего мы делать не будем. Поэтому доставка несет получателя, а Retail Partner Customer ID служит путем обратно в собственную систему партнера.

Кто такой получатель? Три варианта для получателя, у каждого доводы за и против. Вариант A, персональная учетная запись на каждого получателя: не проходит по связи, потому что получатель — клиент партнера; не проходит по объему, около миллиона в год при вдвое большем месте, чем у бизнес-организации; проходит по перекосу, у каждого своя запись; не проходит по изоляции партнеров, потому что смешивает их клиентов; не проходит по удалению, потому что живет дольше доставки; проходит по узнаванию повторных. Отклонено. Вариант B, контакты под розничным партнером: не проходит по связи, ведь это не сотрудники партнера; не проходит по объему; не проходит по перекосу, миллион под тремя-четырьмя организациями; проходит по изоляции, под организацией одного партнера; не проходит по удалению; узнает повторных внутри партнера. Показать и отклонить. Вариант C, поля получателя на рабочем заказе, выделен как выбор контрольной точки 1: единственная связь — это доставка; нет нового объекта; нет нового родителя; один партнер на доставку; удаляется по графику партнера; а повторного получателя не узнают, и это нормально. Внизу: моделируйте человека по той связи, которая у вас на самом деле есть. A: Персональная учетная запись отклонено ЗА Узнает повторного получателя Нет перекоса по родителю: у каждого своя запись ПРОТИВ Клиент партнера, не наш Около 1 млн в год, вдвое больше места Смешивает клиентов партнеров (S2) Живет дольше доставки B: Контакт под розничным партнером: показать и отклонить ЗА Хранится под одним партнером (S2) Повторные известны внутри партнера ПРОТИВ Не сотрудники партнера 1 млн под 3–4 организациями: перекос Живет дольше доставки C: В доставке поля на рабочем заказе: выбор ЗА Единственная связь — это доставка Нет нового объекта, нет нового родителя Один партнер на доставку (S2) Удаляется по графику партнера ПРОТИВ Повторного получателя не узнают: это нормально Моделируйте человека по той связи, которая у вас на самом деле есть. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Стал бы я унифицировать получателей разных партнеров?

Заголовок раздела «Стал бы я унифицировать получателей разных партнеров? »

John Smith, Main Street, 123, появляется в манифесте Redrock и в манифесте Brightwave. Вероятно, это один человек. Должен ли Steve Trucking их унифицировать? Нет, сознательно нет. Унификация получателей разных розничных партнеров нарушила бы S2: партнер никогда не должен видеть получателей другого партнера, а унифицированная идентичность — именно тот мост, через который происходит утечка. Это позиция этой главы в действии: сопоставляйте меньше там, где смешение обходится дорого, а здесь оно обходится очень дорого.

Если розничный партнер позже захочет распознавать повторных получателей в пределах своих доставок, это задача для инструмента разрешения идентичности, например в Data 360, ограниченного этим партнером: карта в стиле реестра, а не персональная учетная запись, и никогда — между партнерами. Карта того, кто есть кто, не дает владения и не дает доступа.

Глава 3 спрашивала, где должны жить данные. Здесь на это отвечают нули:

  • Текущий статус живет на Service Appointment и Work Order. История смен статуса — около 8 млн в год и с ростом — не обязана жить в основном org. Каждое изменение публикуется как событие и хранится в хранилище данных Snowflake. Org хранит текущее состояние; история по-прежнему доступна для обслуживания, операционной работы и аналитики, просто не в операционной базе данных.
  • Фотографии (четыре-пять миллионов в год, на некоторых — люди или интерьер дома) живут вне ядра в хранилище, рассчитанном на такой объем, и загружаются прямо из приложения бригады. Org хранит только то, что ему нужно: небольшую индексную запись на фотографию или просто счетчик и флаг «обязательные фото установки получены». Я предпочитаю более легкий вариант: держать org компактным, а индекс и сроки хранения отдать хранилищу фотографий.
  • GPS-отметки (200 000 в день) остаются в FleetLink и уходят в Snowflake; org нужна только последняя позиция для страницы отслеживания и карты диспетчера.
  • Восемь лет истории RouteDesk (около 5 млн доставок) уходят в хранилище данных или архив, доступный для разбора претензий. Что из этого, если вообще что-то, попадает в org — решение о миграции для части 2.
Контрольная точка 1: что бы спроектировал я Ландшафт контрольной точки 1, что бы спроектировал я, на тех же местах, что и текущий ландшафт из главы 4. Люди слева: 45 диспетчеров в 9 DC партнеров, около 700 человек в бригадах доставки на 330 грузовиках, 100 сотрудников сервиса и офиса, все в Salesforce; около 300 пользователей у 3 розничных партнеров, в портале розничных партнеров; и около миллиона получателей в год, которые открывают страницу отслеживания по ссылке, без входа, и звонят операторам сервиса. В центре один org Salesforce в США с Field Service, корпоративный поставщик удостоверений над ним только для офиса и email в обращение, приносящий обращения. Три розничных партнера справа внизу, Redrock через REST API и вебхуки, Keystone через CSV по SFTP и Brightwave через EDI по сторонней сети, отправляют манифесты в один слой интеграции, который проектируется в части 2, выполняет upsert в Salesforce по ключу партнера и отправляет статус обратно каждому партнеру. Справа: Salesforce отправляет события статуса в Snowflake, где хранятся история статусов и аналитика; FleetLink, где остаются сырые данные GPS, отправляет в Salesforce только последнее положение; Salesforce отправляет число доставок через интеграцию в финансовую ERP, которая выставляет счета партнерам и платит бригадам; фото, 4–5 млн в год, идут из приложения бригад в хранилище фото вне ядра; а RouteDesk выводится из эксплуатации в архив с ее 8 годами истории. Salesforce отправляет сообщение накануне, со ссылкой, через провайдера SMS и email. Внизу: та же компания, что в главе 4; повторного ввода и таблицы больше нет; история и фото живут вне ядра. ВВЕРХУ: ИДЕНТИФИКАЦИЯ, APPEXCHANGE, ВЕБ ЛЮДИ СПРАВА: ВНУТРЕННИЕ СИСТЕМЫ ВНИЗУ: КАНАЛЫ КЛИЕНТОВ СПРАВА ВНИЗУ: ПАРТНЕРЫ И ПРОВАЙДЕРЫ Диспетчеры 45, в 9 DC партнеров Бригады доставки ~700 на 330 грузовиках Сервис и офис 100: сервис, операции, финансы Пользователи розничных партнеров ~300 у 3 партнеров Получатели ~1 млн в год Корпоративный IdP SSO только для офиса Портал розничных партнеров Страница отслеживания ИНТЕГРАЦИЯ Snowflake история статусов, аналитика FleetLink сырые данные GPS остаются здесь Финансовая ERP выставляет счета партнерам, платит бригадам Хранилище фото 4–5 млн в год, вне ядра Архив RouteDesk выведена из эксплуатации; 8 лет истории Телефон операторы сервиса Email email в обращение Провайдер SMS и email сообщение накануне, со ссылкой Redrock REST API, вебхуки Keystone CSV по SFTP Brightwave EDI через стороннюю сеть Salesforce Field Service, один org в США ссылка, без входа только офис звонят обращения внутрь манифесты внутрь статус наружу манифесты внутрь статус наружу манифесты внутрь статус наружу upsert, ключ партнера события статуса только последнее положение число доставок число доставок фото, из приложения бригад накануне, со ссылкой Salesforce сообщество люди идентификация, приложения, веб внутренняя система канал клиентов слой интеграции начинается у системы, которая открывает соединение; подпись говорит, что движется общий сертификат: доверие, без прямого вызова Та же компания, что в главе 4. Повторного ввода и таблицы больше нет; история и фото живут вне ядра. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Контрольная точка 1: как бы я это спроектировал. Те же места, что и на ландшафте главы 4 (Ландшафт Steve Trucking), но без ручного перенабора и электронной таблицы.

  • Розничные партнеры видят только свои доставки (S2). Каждый Work Order несет своего розничного партнера; пользователи портала видят доставки своего партнера, а менеджеры DC — только доставки своего DC.
  • Пользователям партнеров нужна лицензия портала, поддерживающая правила общего доступа и роли: Customer Community Plus или Partner Community. Места на стадионе из главы 3: самые дешевые места не дают того общего доступа, который нужен этому дизайну. Обеим лицензиям нужны роли для внешних пользователей, а Salesforce предупреждает, что большее число ролей замедляет org (Experience Cloud User Licenses (opens in a new tab)). Роль на каждого партнера и на каждый DC — нормально; роль на каждый магазин — нет.

Знать к экзамену. Знайте, какие внешние лицензии поддерживают стандартный общий доступ: Customer Community Plus и Partner Community (с ролями для внешних пользователей), но не Customer Community, которая использует наборы общего доступа (sharing sets).

  • Получателям лицензия не нужна. Страница отслеживания показывает одну доставку по ссылке с токеном, срок действия которого истекает (S3), а не через вход в систему.
  • Следите за перекосом. Сотни тысяч Work Order в год, указывающих на три-четыре организации партнеров, — это перекос данных по организациям (account data skew). Один из вариантов — дочерняя организация для каждого DC под каждым партнером, что распределяет дочерние записи на девять и более частей; архивирование завершенных доставок после окна претензий держит число активных дочерних записей на родителя низким. Этим займется часть 2.

Я бы не создавал персональную учетную запись для каждого получателя только потому, что получатель — физическое лицо. Я бы не вешал миллион контактов на три организации. Я бы не строил пользовательский объект Delivery рядом с Work Order из Field Service. Я бы не унифицировал получателей разных партнеров. Я бы не хранил миллионы фотографий или GPS-отметок в основном хранилище. И я бы не называл унифицированного получателя золотой записью, если бы мы на самом деле не приняли решение о мастеринге.

Часть 1 заложила скелет; часть 2 его проверит. Линейка LDV на третьем году (Work Order, Service Appointment и позиции — все становятся территорией больших объемов в течение двух-трех лет), проектирование запросов для представлений списков с ограничением по партнеру, три входящие интеграции и три потока статусов, миграция из RouteDesk, транзакции в день доставки и дизайн безопасности за порталом. И Steve Trucking тоже будет меняться. Сохраните этот дизайн; вы к нему еще вернетесь.

  • Какие стандартные объекты несут ядро (здесь — объекты Field Service) и какие пользовательские объекты действительно оправданы (здесь — один).
  • Ключ, который сопоставляет строку заказа каждого партнера с доставкой, и почему он принадлежит партнеру.
  • Что такое получатель — исходя из отношений, которые у Steve Trucking с ним на самом деле есть.
  • Унифицировать ли идентичности и где смешение слишком дорого, чтобы рисковать.
  • Что остается в org, что живет вне ядра и от каких лицензий зависит дизайн.