ON Board Documentation

Complete guide to using, configuring, and administering the ON Board user provisioning platform.

What is ON Board?

ON Board is the internal user provisioning platform for Harris Computer. It covers the full lifecycle of onboarding a new employee — from submitting a request to a fully provisioned Microsoft 365 account — with AI-assisted scoring, automatic user creation, Teams Phone integration, and mailbox management.

Everything runs in your browser. There is no backend server — ON Board authenticates via Microsoft (MSAL) and makes direct Microsoft Graph API calls to create users and manage SharePoint data.

Who uses it?

Role Group Access Level
HR / Team Lead (L1) Onboard-L1 Submit requests via Asana (read-only in the app)
IT Admin (Approver) Onboard-Approvers Full access — approve, edit, delete, configure
ℹ️ Contact IT if you cannot sign in — you must be a member of Onboard-Approvers or Onboard-L1.

Signing In

When you first open ON Board, you will see a Sign In Required screen with a single button.

1
Click Sign In with Microsoft

A Microsoft login popup opens.

2
Sign in with your Harris Computer credentials

Use your work account, e.g. m.heuberger@harriscomputer.eu.

3
Dashboard loads automatically

Your name appears in the top-right of the header after sign-in.

💡 Your session is stored in the browser. On subsequent visits you will be signed in automatically unless you explicitly sign out.

The Dashboard — Your Starting Point

After signing in, you land on the main dashboard. This is where all active work happens.

ON Board dashboard — KPI bar, Active Requests queue, Recent Activity, and Live System Feed

The main dashboard: KPI bar (top), Active Requests queue (centre), Recent Activity & Live Feed (bottom)

The License Tiles

Three compact tiles sit across the top of the main area. They show live M365 license consumption pulled directly from your tenant via Microsoft Graph, displayed as used / total.

Tile What it shows
M365 E3 LICENSES E3 seats consumed vs. total purchased
COPILOT LICENSES Microsoft 365 Copilot seats consumed vs. purchased
TEAMS PHONE STD Teams Phone Standard (MCOEV) seats consumed vs. purchased
💡 Tiles show — / — while loading or if the SKU is not present in your tenant.

The Active Requests Queue

Each request appears as a card in the queue. Cards show:

  • Left column: Status badge (READY / NEEDS REVIEW / LOW CONFIDENCE), display name, company, and target email (UPN)
  • Middle column: AI Confidence Score bar (0–100), job title and department badges
  • Right column: Action buttons (Delete / Edit / Approve) and per-request options (Phone Lic checkbox)

The queue is fully scrollable — all requests are visible by scrolling down within the section. There is no pagination. Clicking anywhere on the card body (not the buttons) opens the full Request Details preview.

The Toolbar Buttons

Dashboard toolbar showing all action buttons

The toolbar above the request cards

Button What it does
🔍 Search requests… Filter cards in real time as you type (name, company, UPN, title, department)
➕ New Request Open the new user request form
⚡ Auto-Process All Score + auto-create all high-confidence pending requests immediately
📱 Phone Setup Provision a Teams Phone number for an existing user
👥 Group Access Manage Distribution List memberships and Shared Mailbox permissions
🔄 Refresh Reload all requests from SharePoint

Recent Activity & Live System Feed

Recent Activity (bottom-left) shows the 15 most recently updated entries from SharePoint — useful to track what has been created or changed across all sessions.

Each row is clickable. Clicking a row opens an Activity Detail modal. If the entry is linked to an OnboardingRequest, an "Edit Request" button appears in the modal footer — clicking it opens the full Edit Request form for that record.

Live System Feed (bottom-right) is a real-time terminal that logs every action ON Board takes during your current session — auto-scoring, user creation, warnings, and errors. Each line shows a timestamp, a colour-coded tag (INFO / OK / WARN / ERR), and a description.

How to: Submit a New User Request

This is the most common task. Use it every time a new employee needs to be onboarded.

1
Open the form

Click the blue New Request button in the toolbar.

New Request button highlighted in the toolbar

The New Request button in the toolbar

2
The New User Request form opens

A modal overlay with four sections appears.

New User Request form — Organisation, Identity, Access & Contact, Distribution Lists sections

The New User Request form

3
Organisation — select the Company

Click the Company dropdown and select the company this person belongs to. The company determines the email domain (e.g. selecting Harris Computer Germany → firstname.lastname@harriscomputer.eu).

If the company isn't listed yet, click the + button to the right of the dropdown. See Add a New Company.

4
Identity — name, title, department, license
Field Required Notes
First Name ✅ Only the first word is used for the email (e.g. "Jan Friedrich" → jan)
Last Name ✅ Used in full for the email address
Job Title ✅ Their role, e.g. Software Engineer
Department Optional — omitting it reduces the AI score
Start Date Optional — recorded on the request for reference
License Type E3, E5, F3, or None / Assign Later
5
Access & Contact — Manager UPN

Manager UPN (required): Start typing the manager's name or email. Wait half a second — a dropdown of matching Azure AD users appears. Click the correct person — this fills in their full UPN automatically. Do not type the full UPN by hand unless the person is not found.

6
Distribution Lists (optional)

Type part of a list name (e.g. "HR", "Sales-Team") in the Distribution Lists search field, select from the dropdown. Each selection appears as a chip. Click × to remove a chip.

7
Submit

Click the blue Submit Request button. The request is saved to SharePoint. The AI engine runs immediately — if the score is ≥ 80, the user account is created in Azure AD automatically. If below 80, the card appears in the queue under Needs Review for manual action.

How to: Add a New Company

If the company doesn't appear in the Company dropdown when creating a request, add it first.

1
Open the Add New Company modal

While the New User Request form is open, click the + button to the right of the Company dropdown.

Add New Company modal — Company Name, Email Domain, Country Code, Address fields

The Add New Company modal

2
Fill in the company details
Field Required Example
Company Name ✅ Harris Computer Germany
Email Domain ✅ harriscomputer.eu (no @ prefix, no https://)
Country Code DE (defaults to DE)
Street Address Musterstraße 1
Postal Code 60311
City Frankfurt
Country Germany
⚠️ The Email Domain field is critical. Every user created for this company will get an email address of the form firstname.lastname@[Email Domain]. Make sure it matches the actual domain in Azure AD exactly.
3
Click Create Company

The modal closes and the new company is immediately available in the Company dropdown of the parent form.

How to: Review a Request (Preview)

Before approving, you can inspect all details of a request.

1
Click anywhere on the request card body

(Not on a button.) The Request Details modal opens.

2
Review the details

The modal shows:

  • Status banner — person's name, current status, company, and AI score
  • Identity section — First/Last Name, Job Title, Department, Start Date
  • Access & Contact — Work Email (UPN), Manager UPN, Private Email, Business Phone, License Type
  • AI Scoring Notes (if score < 100) — specific reasons for deductions, e.g. "No private email provided", "Manager UPN could not be verified"
3
Decide what to do

Click Edit to open the edit form and fix any issues. Click Close to go back. Or close the preview and use the card's Approve button to provision the user.

How to: Edit a Request

Use this to correct or update any field before approving.

1
Click Edit

Click Edit on the request card, or click Edit from inside the Request Details preview. The Edit Request modal opens, pre-filled with the current values.

2
Make your changes

All the same fields as the new request form are available, plus:

  • Target UPN (Preview) — a read-only field that shows the generated email address. It updates live as you change the name or company — useful to confirm the UPN before saving.
3
Click Save Changes

The request is updated in SharePoint and the AI score is recalculated. The card refreshes on the dashboard.

How to: Approve a Request (Create the User)

Approving a request triggers the full provisioning sequence in Azure AD.

1
Check the per-card options

Before clicking Approve, check the optional checkbox in the bottom-right of the card:

Option What it does
Phone Lic Also assigns a Teams Phone Standard license during provisioning. Only check if the user needs a Teams Phone number.
2
Click the green Approve button

A loading overlay appears showing the current provisioning step (e.g. "Creating user…", "Assigning license…").

What happens automatically:

  1. Azure AD user account is created with the calculated UPN
  2. Microsoft 365 license is assigned (if selected)
  3. User is added to all default groups (AllStaff, Office365-Users, Teams-Users)
  4. User is added to any Distribution Lists selected on the request
  5. Manager relationship is set in Azure AD
  6. If Phone Lic is checked: Teams Phone Standard license is assigned
  7. Request status updated to Created in SharePoint
3
Confirm the result

A green success toast appears (e.g. "✅ John Doe created successfully"). The card is removed from the queue. The Live System Feed logs the full sequence.

If provisioning fails, a red error notification appears and the card stays with status Failed so you can retry or investigate.

How to: Delete a Request

Click the red Delete button on a request card.

The request is permanently removed from SharePoint and disappears from the queue.

⚠️ This cannot be undone. If you want to reject a request without deleting it, ask your administrator to change its status to Rejected directly in SharePoint.

How to: Auto-Process All High-Confidence Requests

Use this to clear the entire queue of high-scoring requests in a single click — no need to approve each one individually.

1
Click ⚡ Auto-Process All in the toolbar

The system immediately runs the AI scoring engine against every Pending request in the queue.

  • Requests scoring ≥ 80 are automatically created in Azure AD (same provisioning sequence as a manual approval)
  • Requests scoring < 80 are moved to Needs Review and remain in the queue

Progress is logged in real time in the Live System Feed terminal.

2
Review the results

After the process completes, the KPI bar updates: AUTO-PROCESSED shows how many were created; NEEDS REVIEW shows how many still need attention.

💡 When to use: After a batch of requests arrives (e.g. after a CSV import or an Asana sync), click Auto-Process All to instantly handle everything that can be handled automatically.

How to: Set Up a Teams Phone Number

Use this to assign a Teams Direct Routing phone number to a user who already has an account in Azure AD.

1
Click Phone Setup in the toolbar Phone Setup Execution modal — UPN input field and Run button

The Phone Setup modal

2
Enter the user's UPN

Type the full work email address of the user who needs a phone number (e.g. john.doe@harriscomputer.eu).

3
Click Run Phone Setup

A terminal panel expands below, showing each step as it executes:

> Initiating Microsoft Graph connection...
> Validating UPN: john.doe@harriscomputer.eu
> Checking existing SKU bounds...
> Assigning Teams Phone Standard license...
> Waiting for AAD sync...          ← this takes up to 2 minutes
> Querying available DIDs...
> Done — assigning phone number...

The runbook (Invoke-TeamsPhoneAssignment.ps1) runs in Azure Automation in the background. The wait time is configurable in Settings.

4
Wait for completion

The process takes 2–5 minutes. The terminal will show a green "Done" line when finished. If anything fails, an error line appears with details.

How to: Manage Distribution List Memberships

Use this to add an existing Azure AD user to one or more Distribution Lists — for example when someone changes team, or a DL was missed during onboarding.

1
Click Group Access in the toolbar

The Group & Mailbox Access modal opens on the Distribution Lists tab.

Group & Mailbox Access modal — Distribution Lists tab

Group & Mailbox Access — Distribution Lists tab

2
Search for the user

Click into Search User and type the person's name or UPN. Select them from the results. Their Current DL Memberships appear automatically below.

3
Select the DLs to add them to

Click into the Add to Distribution List search box, type a list name, and select from the dropdown. Each selection appears as a chip.

4
Click Add to Selected DLs

The user is added to all selected DLs via Microsoft Graph. A success notification confirms.

ℹ️ Currently ON Board supports adding users to DLs but not removing them through the DL tab. To remove a member, use the Microsoft 365 Admin Center or Exchange Admin Center directly.

How to: Grant or Revoke Shared Mailbox Access

Use this to give a user access to a shared mailbox — or remove access they no longer need.

1
Open Group Access → Shared Mailbox Access tab

Click Group Access in the toolbar, then click the Shared Mailbox Access tab.

Group & Mailbox Access — Shared Mailbox Access tab

Group & Mailbox Access — Shared Mailbox Access tab

2
Fill in the four fields
Field What to enter
Shared Mailbox Type to search for the mailbox (e.g. info@, support@) and select it
Delegate User Type to search for the person who should receive/lose access
Permission Choose one (see table below)
Action Add Permission to grant access, Remove Permission to revoke it

Permission types

Permission What the user can do
Full Access (read + send) Read all mail in the mailbox and send from it — appears in Outlook as a secondary mailbox
Send As Send email that appears to come from the mailbox address
Send on Behalf Send email showing "User Name on behalf of Mailbox Name" in the From field
3
Click Execute via Runbook

The action runs via the Invoke-MailboxPermission.ps1 runbook in Azure Automation. A live terminal panel appears below, streaming the output (polled from SharePoint AuditLog every 2 seconds).

How to: View Provisioning Reports

1
Click Reports in the left sidebar

The Provisioning Reports modal opens.

Provisioning Reports modal — KPI cards, Users Created table, Users by Approver table

The Provisioning Reports modal

2
Review the KPI cards and tables

Three KPI cards: Users Created (30 days) · Pending Requests · Success Rate

Two tables:

  • Users Created Last 30 Days — User · Created Date · Approved By · Company · Department
  • Users by Approver (Last 30 days) — Approver · Users Created · User List
3
Export data (optional)

Both tables have an Export CSV button. Click it to download the table data as a .csv file you can open in Excel.

4
Refresh the data

Click the Refresh button in the modal footer to reload the latest data from SharePoint.

Reference: Request Status Meanings

Status Badge Meaning
Pending Pending Request submitted — AI scoring hasn't run yet, or score is still being calculated
Needs Review Needs Review AI score was below the threshold — a human needs to review and decide
Approved Approved A human approved it — provisioning is starting
Creating Creating User creation is in progress in Azure AD right now
Created Created The user account exists in Azure AD — provisioning complete
Failed Failed Provisioning attempt failed — see the Live System Feed for the error
Rejected Rejected An approver rejected the request — no user was created

Reference: How UPNs Are Generated

ON Board automatically builds the User Principal Name (the user's work email / login) from the request data.

Formula: [firstname].[lastname]@[company-email-domain]

Rules applied to the name

  • Only the first word of the first name is used (e.g. "Jan Friedrich" → jan)
  • German umlauts are expanded to standard ASCII: ü→ue, ö→oe, ä→ae, ß→ss
  • Other accented characters are decomposed to their base letter (e.g. é→e)
  • Everything is lowercased

Examples

Name Company Generated UPN
John Doe Harris Computer Germany john.doe@harriscomputer.eu
Jan Friedrich Müller SIV.AG jan.mueller@siv.de
Felix Lüthke SIV.AG felix.luethke@siv.de
Anne-Marie Schulz Harris Computer Germany annemarie.schulz@harriscomputer.eu

Collision handling

If the generated UPN already exists in Azure AD, the system tries john.doe1@…, then john.doe2@…, up to john.doe9@…. The resulting UPN is shown as a read-only preview in the Edit Request modal.

Reference: The AI Confidence Score

Every request is scored 0–100 before any action is taken. The score reflects how complete and valid the request data is.

Score Card Badge What it means What happens
80–100 ✅ READY All critical fields are present and verifiable Auto-created — no human action needed
50–79 🔍 NEEDS REVIEW Some fields are missing or could not be verified Stays in queue — needs manual approval
0–49 ❌ LOW CONFIDENCE Multiple critical fields are missing or invalid Stays in queue — should be edited before approval

Common reasons for score deductions

  • Private email not provided
  • Manager UPN could not be found in Azure AD
  • Department field is empty
  • Company not found in the CompanyDomains list
  • Start date is in the past
💡 Open the Request Details preview and scroll to AI Scoring Notes to see the exact reasons for any given request. You can adjust the auto-approve threshold in Settings.

Frequently Asked Questions

Q: I submitted a request but don't see it in the queue. Where is it?

The AI engine may have auto-processed it immediately (score ≥ 80). Check:

  1. The AUTO-PROCESSED counter in the KPI bar — if it went up, the user was created automatically
  2. The Live System Feed — you'll see a green [OK] line for the creation
  3. The Recent Activity panel — it will show the request with status Created

If none of these show it, click Refresh — the queue may just not have reloaded yet.

Q: The AI score is very low but all the information looks correct. Why?

Open the request by clicking the card body, then scroll to AI Scoring Notes. Common hidden issues:

  • The manager UPN was typed manually and couldn't be verified — try re-typing it in the search field and selecting from the dropdown
  • The company's email domain in CompanyDomains doesn't match the Azure AD domain exactly
Q: I approved a request and got a "Failed" error. What do I do?
  1. Check the Live System Feed — the red [ERR] line shows what failed
  2. Common causes: license SKU GUID not configured in Settings, the UPN already exists, or a network timeout
  3. Fix the underlying issue, then click Approve again — the card stays in the queue for retries
Q: Can I approve multiple requests at once without clicking each one?
Yes — click ⚡ Auto-Process All. Every pending request that scores ≥ 80 is created automatically. Requests below the threshold remain in the queue for manual review.
Q: How do I remove someone from a Distribution List?
Currently ON Board supports adding users to DLs but not removing them through the DL tab. To remove a member, do it directly in the Microsoft 365 Admin Center or Exchange Admin Center.
Q: The Reports modal shows zeros even though users have been created. Why?
The Reports panel reads from the OnboardingRequests SharePoint list, specifically requests with status Created and a creation date in the last 30 days. Make sure you have Sites.ReadWrite.All permissions on the ONBoard SharePoint site.
Q: What's Mock Mode and when should I use it?
Mock Mode bypasses all Microsoft authentication and Graph API calls, using sample data instead. It activates automatically on localhost. You can also force it via Settings → Enable Mock Mode. Never run with Mock Mode enabled in production — changes will not be saved and no real users will be created.

Admin: Setup & Prerequisites

Prerequisites

  • Azure AD tenant with admin access
  • Azure AD App Registration with delegated permissions (see below)
  • SharePoint Online site at /sites/ONBoard with two lists
  • User Administrator role for the admin using the app

1. Azure AD App Registration

Field Value
App ID 572798ba-7643-4ffc-b457-f28fa8dad7ac
Tenant ID 4ae01105-2790-4652-bbcb-c6dd32603e18

Required API Permissions (Delegated)

Permission Description
User.Read Sign-in and read own profile
User.ReadWrite.All Create and manage all users
Group.ReadWrite.All Manage group memberships
Sites.ReadWrite.All Read/write SharePoint lists
Directory.ReadWrite.All Manage directory objects (manager assignment)
⚠️ Admin consent is required for all permissions above. Azure Portal → App Registrations → ON Board → API Permissions → Grant admin consent.

Redirect URIs (Authentication → Web)

  • https://zealous-island-0a17abf03.4.azurestaticapps.net (production)
  • http://localhost:4280 (local development with SWA CLI)

2. SharePoint Setup

Site URL: https://harriscomputereu.sharepoint.com/sites/ONBoard

List: OnboardingRequests

List ID: 65c922cf-3da8-4621-b53c-8c531992b3c0

Display Name Internal Name Type
Title Title Text
Status field_2 Choice (Pending, NeedsReview, Approved, Creating, Created, Failed, Rejected)
FirstName field_6 Text
LastName field_7 Text
DisplayName field_8 Text
UserPrincipalName field_9 Text
MailNickname field_10 Text
Company field_12 Text
Department field_14 Text
JobTitle field_16 Text
ManagerUPN field_19 Text
StartDate field_21 DateTime
LicenseType field_32 Choice
ProcessingLogs field_53 Multi-line Text
PrivateEmail field_59 Text

List: CompanyDomains

List ID: 29aab1ae-2bd1-4ae9-843d-a352e0c67f57

Display Name Internal Name Type
Title Title Text (company name)
DomainSuffix DomainSuffix Text (e.g. harriscomputer.eu)
CountryCode CountryCode Text (2-letter, e.g. DE)

3. License SKU Configuration

License SKU IDs are tenant-specific GUIDs. Find yours with PowerShell:

Connect-MgGraph -Scopes "Organization.Read.All"
Get-MgSubscribedSku | Select-Object SkuPartNumber, SkuId | Format-Table

Then update either config.js → ONBOARD_CONFIG.licenses (hardcoded, requires redeploy) or the Settings modal → License Configuration section (stored in localStorage, per-browser).

4. Power Automate Flow URLs

Key Purpose Trigger Type
asanaToOnboard Asana task → SharePoint request Webhook
creationComplete Notify when user created HTTP POST
sendCredentials Email credentials to private email HTTP POST

5. Local Development

# Serve locally with SWA CLI
npx @azure/static-web-apps-cli start .

# Or use any static server
npx serve .
python3 -m http.server 8080

For development without Azure credentials, open the browser console and run:

enterMockMode()

This loads fake data and bypasses authentication.

6. Deployment

swa deploy . --app-name ONBoard --resource-group autoOnboarding
Property Value
Resource Group autoOnboarding
Static Web App name ONBoard
Live URL https://zealous-island-0a17abf03.4.azurestaticapps.net

Admin: Architecture

System Overview

ON Board is a client-side SPA — there is no backend server. The admin's browser authenticates via MSAL, then makes direct Microsoft Graph API calls to create users and manage SharePoint data.

┌──────────────────────────────────────────────────────────┐
│  Browser (index.html)                                    │
│                                                          │
│  ┌─────────┐  ┌─────────┐  ┌───────────┐  ┌──────────┐ │
│  │ auth.js │  │ app.js  │  │provision.js│  │ phone.js │ │
│  └────┬────┘  └────┬────┘  └─────┬─────┘  └────┬─────┘ │
│       └────────────┴──────┬──────┴──────────────┘        │
│                      ┌────┴────┐                         │
│                      │graph.js │                         │
│                      └────┬────┘                         │
└───────────────────────────┼──────────────────────────────┘
                            │ HTTPS (Bearer Token)
               ┌────────────┼────────────┐
               │            │            │
        ┌──────┴──────┐ ┌──┴───┐ ┌──────┴──────┐
        │  SharePoint │ │Entra │ │Power Automate│
        │  Lists      │ │ID    │ │  Flows       │
        └─────────────┘ └──────┘ └──────────────┘

Request Lifecycle

Asana Task (L1 submits)
    │
    ▼ Power Automate flow
SharePoint "OnboardingRequests" list [Status: Pending]
    │
    ▼ Dashboard loads via Graph API
ON Board Dashboard (admin sees request card)
    │
    ├─ Edit → PATCH SharePoint item
    ├─ Reject → Status: Rejected
    │
    └─ Approve →
        Status: Creating
        │
        ▼ POST /v1.0/users
        Create Entra ID user
        │
        ▼ PUT /users/{id}/manager/$ref
        Assign manager
        │
        ▼ POST /users/{id}/assignLicense
        Assign M365 license
        │
        ▼ (optional) Assign phone license + number
        │
        ▼ (optional) POST to Power Automate → send credentials email
        │
        Status: Created ✅  (or Failed ❌)

Authentication Flow

  1. Page loads → initAuth() creates MSAL instance
  2. handleRedirectPromise() checks for returning auth redirect
  3. If no session → show sign-in gate
  4. User clicks "Sign In" → loginRedirect() (full-page redirect to Microsoft)
  5. After auth → redirect back → token stored in localStorage
  6. acquireTokenSilent() for API calls → falls back to redirect if expired

Script Load Order

1. msal-browser.min.js  (CDN - Microsoft)
2. config.js            (ONBOARD_CONFIG object)
3. notifications.js     (notify global)
4. loading.js           (loading global)
5. auth.js              (initAuth, getAccessToken)
6. graph.js             (Graph API)
7. provision.js         (provisioning)
8. reports.js           (reporting)
9. phone.js             (phone setup)
10. settings.js         (settings)
11. app.js              (main — depends on everything above)

Key Design Decisions

No backend server
All operations run client-side via delegated Graph API permissions. The signed-in admin's token determines what they can do.
SharePoint as database
Avoids spinning up a separate database. SharePoint lists store all request data with native versioning and permissions.
Field mapping layer
SharePoint auto-generates internal names (field_2, field_6) that differ from display names. graph.js maintains a mapping constant to translate between app-friendly names and SharePoint internals.
Mock mode
enterMockMode() bypasses auth and loads fake data, allowing UI development and testing without Azure credentials.
Password stored in InternalNotes
Generated in-memory by provision.js, passed to the Graph API, and persisted in the SharePoint InternalNotes column for admin reference. Optionally emailed via Power Automate flow.