# Junction Object Patterns

Building on the flexibility described in the Using Your Own Objects page, some organizations have workflows that span *multiple* custom objects. When your hiring and onboarding journey involves several Salesforce objects (e.g., Application, Interview, Offer, Background Check), you can leverage an **Onboarded™ object as a junction object** to consolidate data and simplify your integration architecture.

## Junction Pattern Use Cases

The junction object pattern is especially valuable when you have a **one-to-many mapping scenario** — where a single Onboarded™ record (such as a Placement, Task, Employee, or Employer) needs to be referenced by multiple objects in your Salesforce org.

### Common Scenarios

- **Multiple workflow stages reference one Onboarded™ record.** Your `Application__c`, `Interview__c`, `Offer__c`, and `Background_Check__c` objects all need to track association with the same Onboarded™ record.
- **Multiple tracking objects need visibility into Onboarded™ data.** Different workflow objects need access to the same Onboarded™ status, completion data, or task information.
- **Reporting across multiple objects.** You need to build reports that connect data from various Salesforce objects to Onboarded™ records.
- **Data aggregation from multiple sources.** Information needed for the Onboarded™ API is spread across several Salesforce objects that need to be consolidated before syncing.


> **Without the junction pattern:** You would need to create and maintain separate lookup fields and sync logic on each custom object, leading to duplicated integration code and potential data inconsistencies. Using an Onboarded™ object as a junction centralizes these relationships.


> **Exception — Salesforce HR Employee Service Cloud.** If your organization uses **Salesforce HR Employee Service Cloud**, the junction object pattern described here does not apply. In HR Employee Service Cloud, a single employee's data may be spread across up to four different objects. Onboarded™ provides a dedicated architecture specifically designed to handle this unique data model. Contact your Onboarded™ implementation team for guidance on the HR Employee Service Cloud integration approach.


## Junction Object Selection

Any Onboarded™ object can serve as a junction object depending on your business requirements. Choose the object that best represents the central point of your workflow:

| Onboarded™ Object | Best Used When |
|  --- | --- |
| **Onboarded Placement** | Your workflow centers on job placements, assignments, or task delivery at specific stages |
| **Onboarded Employee** | Your workflow centers on the candidate/employee record and their progression |
| **Onboarded Employer** | Your workflow centers on company/employer records with multiple related processes |
| **Onboarded Task** | Your workflow centers on individual task completion and tracking |
| **Onboarded Job** | Your workflow centers on job requisitions with multiple candidate touchpoints |


## Junction Pattern Benefits

By associating your custom Salesforce objects with an Onboarded™ object acting as a junction, you:

- **Centralize data** – All fields needed for the Onboarded™ API exist in one location
- **Simplify integrations** – One sync operation handles all related data
- **Maintain relationships** – Track which Onboarded™ record corresponds to which source objects
- **Enable reporting** – Build reports that span multiple objects through a single junction point
- **Reduce maintenance** – Changes to sync logic happen in one place, not across multiple objects


> **Key Design Principle — One Source Object per Onboarded™ Record.** Although multiple custom objects may exist in your workflow, each Onboarded™ junction record should be associated with only **ONE** source object at a time for sync purposes. This ensures clear data lineage and prevents sync conflicts.


## Architecture Pattern

Each custom object in your workflow connects to an Onboarded™ object, which serves as the single point of integration with the Onboarded™ API. The following example uses `Onboarded_Placement__c`, but the same pattern applies to any Onboarded™ object:


```
[Application__c] ──────┐
                       │
[Interview__c] ────────┼──→ [Onboarded_Placement__c] ──→ Onboarded API
                       │      (junction object)
[Offer__c] ────────────┤
                       │
[Background_Check__c] ─┘
```

Each custom object can have a lookup to the Onboarded™ junction record. For sync purposes, only **ONE** source object should be actively linked at any time per junction record.

## Implementation Steps

The following subsections demonstrate the junction object pattern using `Onboarded_Placement__c` as an example, in the order you should perform them. Apply the same approach to whichever Onboarded™ object best fits your workflow.

### Custom Attributes and Field Mapping Configuration

All Salesforce field data that needs to be sent to Onboarded™ must be mapped. There are standard fields within the Onboarded API that are populated automatically in the Mapping Configuration; however, additional mapping rows can be added. This is done by using the **Create Custom Attribute** or **Retrieve Custom Attribute** buttons:

#### Create Custom Attribute (New Attributes)

Use this approach to create a **new** custom attribute that doesn't yet exist in your Onboarded™ account:

1. Navigate to **Onboarded Setup** > **Field Mapping**
2. Select the desired Onboarded™ object (e.g., Placement)
3. Click the **Create Custom Attribute** button
4. Select a **Scalar Type** (String, Boolean, Date, DateTime, Integer, Decimal, or Address)
5. Enter the **Attribute Name** (API name) and **Attribute Label** (display name)
6. Optionally check **"Add to OnboardedMappings__c"** to automatically add the attribute to the field mapping list
7. Click **Create**


This creates the custom attribute in your Onboarded™ account via API and optionally adds it to your Salesforce field mappings in one step.

#### Retrieve Custom Attributes (Existing Attributes)

Use this approach to import custom attributes that **already exist** in your Onboarded™ account:

1. Create the custom attribute in your Onboarded™ account (via the Onboarded™ application)
2. Navigate to **Onboarded Setup** > **Field Mapping** in Salesforce
3. Select the desired Onboarded™ object (e.g., Placement)
4. Click the **Retrieve Custom Attributes** button
5. The system queries your Onboarded™ account and displays available custom attributes not yet in your mappings
6. Select the attributes you want to import
7. Click **Import Selected**


This adds the selected attributes to your Salesforce field mappings, making them available for data sync.

#### Example Placement Custom Attributes

Common custom attributes you might create for a Placement junction object:

| Attribute Name | Scalar Type | Description |
|  --- | --- | --- |
| `start_date` | Date | Candidate's anticipated start date |
| `department` | String | Assigned department |
| `manager_name` | String | Hiring manager name |
| `office_location` | String | Work location |
| `compensation` | Decimal | Offered compensation |


Once custom attributes are added to your mappings, configure the **Salesforce Field** mapping for each attribute to specify which Salesforce field will hold the data. This must be completed before proceeding with the remaining steps.

### Source Object Lookup Fields

On your junction object, create **lookup fields** to each source object that will be associated with it. This enables relationship navigation and the write-back process below.

**Example:** If using `Onboarded_Placement__c` as a junction for hiring workflow objects:

| Field Label | API Name | Type | Related To |
|  --- | --- | --- | --- |
| Offer | `Offer__c` | Lookup | `Offer__c` |
| Background Check | `Background_Check__c` | Lookup | `Background_Check__c` |


*Create a lookup field for each source object type that may trigger the creation of or be associated with the junction record.*

### Junction Record Creation Flow

Create a Record-Triggered Flow on your source object that fires when the business criteria for creating the junction record is met.

**Example:** Creating an `Onboarded_Placement__c` when an `Offer__c` is accepted.

#### Flow Settings

- **Flow Type:** Record-Triggered Flow
- **Object:** `Offer__c` (or your source object)
- **Trigger:** After Insert or After Update
- **Entry Conditions:** Status equals "Accepted" (or your criteria)


#### Flow Elements

1. **Get Records** – Query the related Employee and Employer Onboarded IDs:
  - Get the Contact/Employee record to retrieve `Onboarded_Id__c`
  - Get the Account/Employer record to retrieve `Onboarded_Id__c`
2. **Create Records** – Create the `Onboarded_Placement__c` record with:
  - `Onboarded_Employee__c` = [Employee lookup]
  - `Onboarded_Employer__c` = [Employer lookup]
  - `Offer__c` = `{!$Record.Id}` (lookup to the source object)
  - `Start_Date__c` = `{!$Record.Start_Date__c}`
  - `Department__c` = `{!$Record.Department__c}`
  - [Map additional fields from the source object]
3. **Store the Record Id** – Capture the newly created junction record's Id for the next step


### Junction Record Sync

After creating the junction record, use the **Onboarded™ Data Sync** invocable action to sync it to the Onboarded™ system.

#### Action Element

- Search for: **Onboarded Data Sync**
- Set Input Values:
  - **recordId:** The Id of the junction record created in the previous subsection
  - **sObjectName:** The API name of your junction object (e.g., `Onboarded_Placement__c`)
  - **onboardedObjectType:** The Onboarded™ object type (e.g., `Placement`)
  - **operation:** `Create`


> The invocable action uses your configured field mappings to automatically send all mapped custom attributes to the Onboarded™ API.


### Onboarded ID Writeback

When the sync completes, the `Onboarded_Id__c` field on the junction record is populated with the Onboarded™ system's record ID (e.g., `plcmt_abc123` for Placements, `emp_xyz789` for Employees). Create a separate Flow to write this value back to your source object for reference.

#### Scheduled Flow (Recommended for Async Operations)

Since the Onboarded™ Data Sync may run asynchronously via Queueable, the `Onboarded_Id__c` won't be immediately available. Use a Scheduled Flow:

- **Flow Type:** Schedule-Triggered Flow
- **Frequency:** Every 15 minutes (or as needed)


Flow Elements:

1. **Get Records** – Query junction records where:
  - `Onboarded_Id__c` IS NOT NULL
  - The source object lookup field IS NOT NULL (e.g., `Offer__c` IS NOT NULL)
  - Related source record's Onboarded ID field IS NULL
2. **Loop** – For each junction record:
  - Build an update record for the source object
  - Set the source object's Onboarded ID field = junction record's `Onboarded_Id__c`
3. **Update Records** – Commit the source record updates


#### Record-Triggered Flow on Junction Object (For Synchronous Operations)

If using Screen Flows where sync is synchronous:

- **Flow Type:** Record-Triggered Flow
- **Object:** Your junction object (e.g., `Onboarded_Placement__c`)
- **Trigger:** After Update
- **Entry Conditions:** `Onboarded_Id__c` IS NOT NULL AND `Onboarded_Id__c` IS CHANGED


Flow Elements:

1. **Decision** – Check if the source object lookup is populated (e.g., `Offer__c` IS NOT NULL)
2. **Update Records** – Update the source record:
  - Filter by Id = the lookup field value (e.g., `{!$Record.Offer__c}`)
  - Set the source object's Onboarded ID field = `{!$Record.Onboarded_Id__c}`


## Hiring Workflow Example

**Your org uses these objects in the hiring process:**

- `Job_Application__c` – Initial application
- `Interview__c` – Interview scheduling and feedback
- `Offer__c` – Offer details and acceptance
- `Background_Check__c` – Pre-employment verification


**Implementation Flow:**

1. When an `Offer__c` record status changes to "Accepted":
  - Flow creates `Onboarded_Placement__c` with data from the Offer
  - Flow calls **Onboarded™ Data Sync** to create the Placement in Onboarded™
  - Candidate receives their onboarding tasks
2. The Onboarded™ `placement_id` is written back to `Offer__c.Placement_Id__c`
3. If `Background_Check__c` needs to trigger additional tasks later:
  - A new Placement is created (or the existing one is updated)
  - The same pattern applies


## Junction Pattern Summary

| Step | Action | Tool |
|  --- | --- | --- |
| 1 | Add custom attributes and configure field mappings | Setup > Object Manager / Onboarded Setup |
| 2 | Create lookup fields to each source object | Setup > Object Manager |
| 3 | Build Flow to create junction record from source object | Flow Builder |
| 4 | Add Onboarded™ Data Sync action to the Flow | Flow Builder |
| 5 | Build Flow to write Onboarded™ ID back to source | Flow Builder |


> **Best Practice:** Document your junction object pattern for your team. Create a simple diagram showing which source objects connect through your chosen Onboarded™ junction object and at what stage of your workflow each junction record is created.