The Talent Accelerator — Product Handbook¶
The single source of truth for the whole company¶
Who this is for: everyone — CEO, Product Managers, Business Analysts, QA Engineers, Frontend & Backend Developers, DevOps, Customer Success, Support, and every new employee.
How to read it: the early sections (1–6) are written in plain English and need no technical background. The later sections (7–13) add technical depth for engineers. A Glossary (14) and FAQ (15) are at the end. Jump to whatever you need using the table of contents.
📌 Ground rule for this document: every statement here is based on the actual product code (frontend and backend). Where something genuinely cannot be determined from the code, it says "Unable to determine from the available code." Nothing is guessed or invented.
Table of Contents¶
| # | Section | Best for |
|---|---|---|
| 1 | Executive Summary | Everyone, especially leadership |
| 2 | Product Overview | Everyone |
| 3 | Product Modules | PMs, BAs, Support, new joiners |
| 4 | Complete User Journey | PMs, QA, Support, Customer Success |
| 5 | Feature Documentation | PMs, QA, BAs |
| 6 | User Roles & Permissions | Everyone |
| 7 | System Overview | Everyone (light), Engineers |
| 8 | Data Flow | Engineers, QA |
| 9 | Business Rules | PMs, BAs, QA |
| 10 | Validation Rules | QA, Developers |
| 11 | Integrations | Engineers, PMs, Support |
| 12 | Testing Perspective | QA |
| 13 | Technical Overview | Developers, DevOps |
| 14 | Glossary | Everyone |
| 15 | Frequently Asked Questions | Everyone |
1. Executive Summary¶
What is the product?¶
The Talent Accelerator (internally called "TOM") is a compensation-management software platform used by companies to design, benchmark, and deliver employee pay.
Think of it as the "command center for how a company pays its people" — from setting up salary structures, to evaluating how important a job is, to building a specific pay offer for a candidate, to comparing that pay against the market.
Why does it exist?¶
Deciding what to pay employees is hard, high-stakes, and easy to get wrong. Companies struggle to answer questions like:
- "Is this salary offer competitive, or are we overpaying / underpaying?"
- "How does this role compare to similar roles in our industry?"
- "Are we paying men and women fairly for the same work?"
- "What grade (seniority level) does this job deserve?"
The Talent Accelerator exists to answer these questions with data instead of guesswork.
What business problem does it solve?¶
| Problem | How the product solves it |
|---|---|
| Pay decisions are inconsistent and subjective | Central, structured pay data (grades, salary ranges, bonuses, benefits) per company |
| Hard to know if an offer is competitive | Live market benchmarking against real pay data |
| Job seniority is decided by opinion | A structured job evaluation questionnaire that scores a role and assigns a grade |
| Building an offer is slow and error-prone | A guided offer builder that auto-fills data and calculates totals |
| No visibility into pay fairness | Dashboards showing pay gaps, compa-ratios, and hiring trends |
| Manual, spreadsheet-heavy work | Bulk CSV upload/download and AI-assisted data mapping |
Who uses it?¶
- Companies (clients / tenants) — HR, compensation, and reward teams who manage their pay data and build offers.
- The Talent Accelerator's own staff (internal admins) — who set up client companies, manage the shared reference data (industries, job functions, grades), and support clients.
What value does it provide?¶
- Faster, more confident pay decisions backed by market and internal data.
- Consistency and fairness across the organization.
- Compliance and transparency (e.g., gender pay-gap visibility).
- Time saved through automation, templates, and AI assistance.
2. Product Overview¶
Main purpose¶
Give companies one place to: 1. Set up their pay framework (grades, salary ranges, bonuses, benefits). 2. Evaluate jobs to decide their seniority/grade. 3. Build competitive pay offers for candidates. 4. Benchmark pay against the market. 5. Analyze compensation trends and fairness.
Target users¶
| User group | What they do here |
|---|---|
| Company HR / Reward teams | Maintain pay data, evaluate jobs, build offers, run reports |
| Company leadership | View dashboards and analytics |
| The Talent Accelerator internal staff | Onboard companies, manage shared data, support clients |
| New hires being made an offer | (Indirectly) receive the offer email/PDF generated by the system |
Major capabilities¶
mindmap
root((Talent<br/>Accelerator))
Compensation Setup
Job Grades
Salary Ranges
Cash Allowances
Bonuses (STI)
Equity (LTI)
Benefits
Offer Modelling
Build offers
Auto-populate
AI insights
Email & PDF
Versions & revisions
Job Evaluation
Factor questionnaire
Grade result
Job library
Benchmarking
Live Pay reports
By title / by grade
Peer baskets
Analytics
Compa-ratio
Pay gap
Hiring trends
Administration
Companies
Users & roles
Applications & access
High-level workflow (the big picture)¶
flowchart LR
A[Internal staff<br/>create a Company] --> B[Grant the company<br/>Applications: TOM / JE / LBT]
B --> C[Company admin<br/>adds users & sets their access]
C --> D[Company sets up<br/>pay data: grades, salary, bonuses...]
D --> E[Evaluate jobs<br/>to assign grades]
D --> F[Build candidate offers]
D --> G[Run benchmarking reports]
F --> H[Analytics dashboards]
G --> H
Core concepts (learn these five and everything else makes sense)¶
| Concept | Plain-English meaning |
|---|---|
| Company (Tenant) | A client organization. All data belongs to one company. Companies never see each other's data. |
| Application | A separate tool inside the platform. There are five: TOM, JE, LBT, Dashboard, and SSO. A company is entitled to some of them; a user is given access to some of those. |
| Grade | A seniority level for a job (e.g., a numeric band). Salary, bonuses, and benefits are usually defined per grade. |
| Offer | A specific proposed pay package for one candidate — base salary, bonus, equity, benefits, sign-on, and totals. |
| Version | Most pay data is kept in historical snapshots. Only one version is "active" at a time, but old versions are preserved. |
Product terminology (the "applications")¶
| App name in code | Friendly name | What it's for |
|---|---|---|
| SSO | Sign-in & Admin Portal | Where everyone logs in, picks an app and a company, and where admins manage companies & users |
| TOM | Total Offer Management | The main app: pay data + building candidate offers + AI insights |
JE (taref-cicd) |
Job Evaluation | Score a job and assign it a grade; job libraries |
| LBT | Live Pay Benchmarking Tool | Generate market pay benchmarking reports |
Dashboard (ADMIN_PANEL) |
Compensation Dashboard | Charts for compa-ratio, pay gaps, hiring trends |
💡 Callout — one login, many apps. A user logs in once in the Sign-in Portal (SSO). They then pick which app to enter. Behind the scenes a shared browser cookie carries their identity between apps, so they never log in again while moving around. This is called Single Sign-On (SSO).
3. Product Modules¶
Each "module" below is a major area of the product. The five applications are the user-facing modules; the rest are supporting capabilities that live inside them.
3.1 Sign-in & Admin Portal (SSO)¶
| Aspect | Detail |
|---|---|
| Purpose | The front door. Log in, choose an app, choose a company, and (for admins) manage companies and users. |
| Business value | One secure entry point; central control over who can use what. |
| Main features | Login / forgot-password / reset-password; App picker; Company picker; create & edit companies; add & configure company users; manage shared data (sectors, industries, job functions, grade maps). |
| Users | Everyone logs in here. Internal admins and company admins do management here. |
| Inputs | Email + password; company details; user details and their access settings. |
| Outputs | A signed-in session (shared across apps); created companies and users; entitlement settings. |
| Dependencies | The backend identity system (users, roles, permissions, companies). |
| Connects to | All other apps — it hands off the logged-in session and the chosen company to TOM, JE, LBT, and Dashboard. |
3.2 Total Offer Management (TOM)¶
| Aspect | Detail |
|---|---|
| Purpose | Maintain a company's pay data and build candidate offers. |
| Business value | Faster, data-backed, consistent offers; the core revenue product. |
| Main features | Manage Job Grades, Salary Ranges, Cash Allowances, Benefit Plans, Short-Term Incentives (bonuses), Long-Term Incentives (equity), Internal Payroll data, Market data; a 3-step Offer Builder; AI insight suggestions; email/PDF offer generation; offer versions/revisions; a compensation analytics dashboard. |
| Users | Company HR / reward teams (roles: Company Super User, Admin, User, Business Access). |
| Inputs | Pay data (typed in forms or uploaded via CSV); candidate & position details. |
| Outputs | Saved pay data (versioned); offers (draft → placed → accepted/rejected); offer emails & PDFs; dashboard charts. |
| Dependencies | Company setup data; grades; job-function mappings. |
| Connects to | Uses grades that JE helps define; feeds data that LBT and Dashboard analyze. |
3.3 Job Evaluation (JE)¶
| Aspect | Detail |
|---|---|
| Purpose | Decide how senior/important a job is, objectively, and assign it a grade. |
| Business value | Removes subjectivity from grading; underpins fair pay structures. |
| Main features | Create jobs (individually or via mass upload); a factor-based questionnaire (Knowledge & Skills, Problem Solving, Stakeholder Management, Decision Impact, Financial/Non-financial Responsibility); an automatic grade result; Job Library & PayNet reference libraries; a Custom Job Library with job-description document uploads. |
| Users | Company users (evaluate jobs) and internal admins (maintain grade definitions & libraries). |
| Inputs | Job details; questionnaire answers; job-description documents. |
| Outputs | An evaluation score and a resulting grade; a submitted, locked evaluation. |
| Dependencies | Company setup; company job functions; grade-point definitions. |
| Connects to | The grades it produces are the same grades TOM uses for salary ranges and offers. |
3.4 Live Pay Benchmarking Tool (LBT)¶
| Aspect | Detail |
|---|---|
| Purpose | Compare a company's pay against the market. |
| Business value | Answers "are we competitive?" with real data; supports pay decisions and negotiations. |
| Main features | A 5-step report wizard (location & dates, peer selection, reward elements, percentiles, data-aging); a live "Benchmarking by Function/Title" view with percentile bars; report status tracking and CSV download; custom peer baskets. |
| Users | Company users with benchmarking access. |
| Inputs | Filters (country, grade, job function, dates), peer companies, chosen percentiles. |
| Outputs | A downloadable benchmarking report (CSV) and on-screen percentile statistics. |
| Dependencies | Offers data and internal payroll data across companies; grades and job functions. |
| Connects to | Reads the same pay data maintained in TOM; access is granted via a "Bench Marking Tool" switch when provisioning a user. |
3.5 Compensation Dashboard (ADMIN_PANEL)¶
| Aspect | Detail |
|---|---|
| Purpose | Visualize compensation health and fairness. |
| Business value | At-a-glance insight for leadership and reward teams. |
| Main features | Charts for Compa-Ratio (new hires vs existing) by department and grade, Total Cash vs Total Remuneration increases, pay mix split, new vs critical hires, and men-vs-women pay gap (by new offers and by payroll); cascading filters and date ranges. |
| Users | Company users with dashboard-view permission. |
| Inputs | Filters (business unit, region, country, job function, grade, dates). |
| Outputs | Interactive charts and KPIs. |
| Dependencies | Offers, internal payroll, and salary-range data. |
| Connects to | Analyzes data created in TOM; shares the same login and company context. |
3.6 Supporting capabilities (inside the apps)¶
| Capability | What it does | Where it appears |
|---|---|---|
| Bulk CSV Upload/Download | Import or export any pay dataset as a spreadsheet file | TOM (all pay data screens) |
| AI Job-Function Mapping | Suggests how a company's job titles map to the standard catalog using AI | TOM / CSV area |
| AI Insights & Alerts | LLM-generated pay insights and analysis on offers | TOM (Offer Builder) |
| Email & PDF generation | Turns an offer into a branded email preview and a downloadable PDF | TOM (Offers) |
| Versioning | Keeps historical snapshots of pay data; one active version at a time | TOM (all pay data), Offers (revisions) |
| Company & Org setup | Business units, regions, countries, legal entities, currencies, stock tracking | SSO + TOM |
4. Complete User Journey¶
4.1 The end-to-end journey (from nothing to a delivered offer)¶
flowchart TD
subgraph "Internal staff (The Talent Accelerator)"
S1[Create the client Company] --> S2[Choose which Applications<br/>the company gets: TOM / JE / LBT]
S2 --> S3[A Company Super User account<br/>is created automatically +<br/>emailed a one-time password]
end
subgraph "Company admin"
C1[Log in via SSO<br/>set a new password] --> C2[Add company users<br/>set their app access, scope & role]
C2 --> C3[Set up pay data:<br/>grades, salary, allowances,<br/>bonuses, equity, benefits]
end
subgraph "Company users"
U1[Evaluate jobs in JE<br/>→ get grades] --> U2[Build a candidate offer in TOM]
U2 --> U3[Auto-populate + AI insights]
U3 --> U4[Place the offer<br/>preview email / PDF]
U4 --> U5[Mark Accepted / Rejected<br/>or Revise into a new version]
U6[Run benchmarking in LBT] -.informs.-> U2
U7[View Dashboards] -.monitors.-> U5
end
S3 --> C1
C3 --> U1
4.2 Signing in and moving between apps (the SSO journey)¶
sequenceDiagram
participant U as User
participant SSO as Sign-in Portal (SSO)
participant Cookie as Shared browser cookie
participant App as TOM / JE / LBT / Dashboard
participant API as Backend
U->>SSO: Enter email + password
SSO->>API: POST /v2/auth/login/
API-->>SSO: Access + Refresh tokens
SSO->>Cookie: Store identity (user_data) on shared domain
SSO->>U: Show App Picker
U->>SSO: Choose an app (e.g. TOM) + a company
SSO->>Cookie: Store selected_application + selected_company
SSO->>App: Open the chosen app in the browser
App->>Cookie: Read shared identity + selected company
App->>API: GET /v2/auth/verify-user/?application=TOM&company_id=...
API-->>App: Confirms access + this user's permissions for TOM
App-->>U: App opens — no second login needed
💡 Callout — what "verify-user" does. When you enter an app, the app asks the backend "does this person have access to me, for this company, and what exactly can they do?" The backend replies with the user's permissions for that specific app. This is why the same person can be an Admin in one app and a read-only user in another.
4.3 Building an offer (the headline journey in TOM)¶
flowchart LR
A[Step 1<br/>Position details<br/>title, grade, location] --> B[Step 2<br/>Candidate details<br/>experience, current pay]
B --> C[Step 3<br/>Offer Modeller<br/>base, bonus, equity,<br/>benefits, sign-on]
C --> D{Save as?}
D -->|Draft| E[Saved as Draft]
D -->|Place| F[Status = PLACED]
F --> G[Preview email / download PDF]
F --> H[Mark ACCEPTED / REJECTED]
F --> I[Revise → creates a new version<br/>original becomes EDITED]
C -. AI Suggestion Bot .-> J[Compa-ratio, retention risk,<br/>pay-trend, conversion, etc.]
C -. Auto-populate .-> K[Pre-fills market & internal pay data]
4.4 Evaluating a job (the headline journey in JE)¶
flowchart LR
A[Create a job<br/>individually or mass-upload] --> B[Open the evaluation<br/>questionnaire]
B --> C[Answer each factor:<br/>Knowledge, Problem-solving,<br/>Stakeholders, Decision impact,<br/>Financial responsibility]
C --> D[Upload org chart / JD<br/>optional]
D --> E[System scores it →<br/>evaluation_result = a Grade]
E --> F[Status: open → evaluated]
F --> G[Submit for approval →<br/>status closed / locked]
4.5 Generating a benchmarking report (the LBT journey)¶
flowchart LR
A[Name the report] --> B[Step 1: Location, dates,<br/>report type, data source, grade, function]
B --> C[Step 2: Sectors/Industries<br/>or a custom peer basket]
C --> D[Step 3: Reward elements]
D --> E[Step 4: Percentiles]
E --> F[Step 5: Data-aging factors]
F --> G[Submit → report is queued<br/>status = Processing]
G --> H[Page polls every 4s<br/>until Completed]
H --> I[Download CSV report<br/>+ success email]
5. Feature Documentation¶
This section documents each major feature: what it does, why, who uses it, its business rules, validations, expected behavior, and how it connects to the rest of the system.
Format note: for brevity, "Company user" means someone with an appropriate company role and permission; "Internal admin" means Talent Accelerator staff (a
TOM_*role).
5.1 Company Setup & Provisioning¶
| What it does | Creates a client company along with its first admin user, its app entitlements, default roles, and initial stock data. |
| Why it exists | Every piece of data belongs to a company; a company must exist before anything else can happen. |
| Who uses it | Internal admins (in the SSO portal). |
| Business rules | Company name, contact email, and phone must be unique. Creating a company automatically creates a Company Super User and emails them a one-time password. The company's Applications list controls which apps it can use. |
| Validations | Required fields (name, address, HQ country, financial year, contract dates, logos, country, currency). Duplicate email/phone/name rejected. |
| Expected behavior | On success, the company, its super user, its roles, and its applications exist; the super user receives an email. |
| Connects to | Everything — it is the root of all data. |
5.2 User Management & Access Control¶
| What it does | Adds users to a company and configures, per application, whether they have access, what data they can see (scope), and what role/permissions they get. |
| Why it exists | Companies need to control who can do what, separately for each app. |
| Who uses it | Internal admins and Company admins (in SSO). |
| Business rules | Access is configured on TOM and JE tabs (only for apps the company owns). A "Grant Access" switch turns an app on for the user. Scope is set by choosing Business Units → Regions → Countries → Grades → Company Job Functions. A Role is chosen (or custom), which applies a preset permission set. A "Bench Marking Tool" switch (shown only if the company owns LBT) grants LBT report permissions. A "TOM Dashboard" switch grants dashboard viewing. |
| Validations | At least one grade must be selected in the user's scope unless the role is Company Super User or the only app is JE. |
| Expected behavior | The user can log in and only enter/see what they were granted. |
| Connects to | Drives the permission checks in every app (see §6). |
5.3 Compensation Reference Data (Grades, Salary, Allowances, STI, LTI, Benefits, Payroll, Market)¶
| What it does | Lets a company maintain each pay dataset in a searchable, sortable table with Create, Upload (CSV), Download (CSV), and Versions actions. |
| Why it exists | This is the structured pay data that offers, benchmarking, and dashboards all rely on. |
| Who uses it | Company users with the matching view/create/update permission. |
| Business rules | Data is versioned — only one version is active per dataset per company; uploading new data creates a new version and deactivates the old. Data can be global (all countries) or country-specific. "Global" creation is restricted to certain roles. |
| Validations | Uploaded CSVs are validated for missing values, duplicates, valid enums, numeric/date columns, and that referenced countries/currencies/grades exist and are within the user's allowed scope. Invalid uploads trigger an error email and are rejected. |
| Expected behavior | Valid upload → new active version + success email. Invalid → rejected + error email listing the problems. |
| Connects to | Read by the Offer Builder (auto-populate), LBT, and Dashboards. |
5.4 Offer Builder (Offer Modeller) — headline feature¶
| What it does | A 3-step wizard to build a full candidate pay offer: position, candidate, then the compensation model (base, bonus, equity, benefits, sign-on, and totals). |
| Why it exists | Turning pay data into a concrete, competitive, correctly-calculated offer is the product's core job. |
| Who uses it | Company users with offer permissions. |
| Business rules | An offer moves through statuses: Drafted → Placed → Accepted/Rejected, and Edited when revised. A revision archives the current offer as a new version (original marked EDITED). Only Placed offers can be revised. Only Draft offers can be deleted. The offer's job function/sub-function must be mapped to the standard catalog. |
| Validations | Grade + country must belong to the company; reporting grade must exist; company function must be mapped to a standard function. |
| Expected behavior | Auto-populate pre-fills market/internal data; totals recalculate; AI insights appear; email/PDF can be previewed; status transitions follow the rules above. |
| Connects to | Reads compensation reference data; produces data analyzed by Dashboards and (across companies) LBT. |
💡 Callout — the compensation formula. The offer's numbers (compa-ratio, target total cash, total remuneration, % differences) are computed by a shared compensation formula engine. Backend engineers: see
services/offer_formula.pyand section 6.2 of the Backend Documentation. Known risk: there are currently three copies of this math (offer list, email/PDF, comparison) that can drift — see §12.
5.5 AI Insights & Suggestions¶
| What it does | Generates short, plain-language pay insights and analysis alerts on an offer (e.g., compa-ratio review, hire-conversion analysis, critical-pay positioning, retention risk, roles-in-demand, one-time-payment suggestions, pay-trend). |
| Why it exists | Helps users make better, faster decisions with AI-generated guidance. |
| Who uses it | Company users building offers (some roles are blocked from AI insights). |
| Business rules | Results are cached to reduce cost/latency. If the AI service is unavailable, the system falls back to predefined messages (Groq-based insights) or returns nothing gracefully (OpenAI-based alerts). |
| Validations | Requires a valid offer and company; input is validated per insight type. |
| Expected behavior | An insight message appears; on failure, a safe fallback message is shown. |
| Connects to | Reads offer + payroll + market data; uses external AI providers (see §11). |
5.6 Job Evaluation¶
| What it does | Scores a job across several factors and maps the total to a grade. |
| Why it exists | Objective, repeatable job grading. |
| Who uses it | Company users (evaluate); internal admins (maintain grade definitions/libraries). |
| Business rules | Two evaluation models: Financial (uses revenue responsibility) and Non-financial. Lifecycle: open → evaluated → close (submitted). A closed evaluation is locked. |
| Validations | All factor questions are required to run an evaluation; the job function/sub-function must be mapped; the country must be within the user's scope. |
| Expected behavior | On evaluation, the system sums factor points, finds the matching grade band, and stores the resulting grade. |
| Connects to | Produces grades used by TOM's salary ranges and offers. |
5.7 Live Pay Benchmarking¶
| What it does | Aggregates market pay from offers and payroll into percentile statistics and produces a downloadable report; also offers an instant "by function/title" view. |
| Why it exists | To answer "is our pay competitive?" with real data. |
| Who uses it | Company users with LBT access. |
| Business rules | Reports run in the background (queued, status-tracked). Statistics are shown as organization-weighted and incumbent-weighted. Small samples are suppressed (e.g., a percentile needs a minimum number of companies/observations) — except a company always sees its own data. Data-aging factors adjust older data. A custom peer basket requires enough companies (≥10). Individual "by title" reports are subject to a per-company quota. |
| Validations | Enough data must exist or the report is rejected ("not enough data"); an industry-scope expansion prompt appears when too few peers match. |
| Expected behavior | Report is generated asynchronously; on completion the user gets a success email and can download the CSV. |
| Connects to | Reads pay data across companies; access gated by the "Bench Marking Tool" switch. |
5.8 Compensation Dashboards¶
| What it does | Shows compensation analytics: compa-ratios, pay-mix, hiring trends, and gender pay gap. |
| Why it exists | Visibility and monitoring of pay health and fairness. |
| Who uses it | Company users with dashboard-view permission. |
| Business rules | Metrics are computed from offers, payroll, and salary ranges; currency is converted to the company currency. |
| Validations | Filters constrain the data; results depend on available data. |
| Expected behavior | Interactive charts update as filters/date ranges change. |
| Connects to | Reads data created in TOM. |
5.9 Bulk CSV Upload & AI Mapping¶
| What it does | Import/export any pay dataset via CSV; AI suggests how company job functions map to the standard catalog. |
| Why it exists | Companies have lots of existing data in spreadsheets; manual mapping is slow. |
| Who uses it | Company users and internal admins. |
| Business rules | Uploads are validated then versioned. AI mapping runs synchronously (small) or in the background with S3 storage (large), and is idempotent (a repeat with the same data reuses the prior result). |
| Validations | See §10 for the CSV validation list. |
| Expected behavior | Valid data is loaded; AI mapping produces a downloadable suggestions file. |
| Connects to | Populates the reference data used everywhere. |
6. User Roles & Permissions¶
6.1 User types¶
There are two families of users.
| Family | Roles | Who they are |
|---|---|---|
| Internal (Talent Accelerator staff) | TOM_MASTER_USER, TOM_SUPER_USER, TOM_ADMIN, TOM_SALES |
Platform operators — set up companies, manage shared data, support clients |
| Company (client) users | COMPANY_SUPER_USER, COMPANY_ADMIN, COMPANY_USER, COMPANY_BUSINESS_ACCESS |
The client's own team members |
6.2 Access levels (simplified)¶
| Role | Typical access |
|---|---|
| TOM_MASTER_USER | Highest internal level — effectively unrestricted; bypasses most permission checks |
| TOM_SUPER_USER / TOM_ADMIN / TOM_SALES | Internal admins with specific permission sets for managing shared data and companies |
| COMPANY_SUPER_USER | The company's top admin — broad access within their own company; auto-created with the company |
| COMPANY_ADMIN | Company admin with a defined permission set |
| COMPANY_USER | Standard company user, scoped to specific data |
| COMPANY_BUSINESS_ACCESS | The most restricted company user |
6.3 How permissions work (two layers)¶
flowchart TB
subgraph "Layer 1 — Can you perform this action?"
A[Each action has a permission<br/>e.g. CREATE_OFFER, VIEW_SALARY_RANGE] --> B[Your role holds a set of permissions]
end
subgraph "Layer 2 — Which rows can you see?"
C[Your access scope is stored per user:<br/>Business Units, Regions, Countries,<br/>Grades, Job Functions] --> D[Data is filtered to only what<br/>you're scoped to]
end
B --> E[Action allowed or denied]
D --> E
- Action permissions — every action (create an offer, view salary ranges, etc.) has a named permission. Your role holds a set of these.
- Row-level scope — separately, each user has an allowed scope (which business units, regions, countries, grades, and job functions they can see). The system filters data to that scope.
⚠️ Callout for QA & Engineers — a subtle permission behavior. In the backend, a permission check "passes" for any HTTP method it doesn't explicitly guard. This means that when several permission classes are stacked on one screen (view + edit + delete), each action is effectively gated only by its matching permission, not all of them together. A misconfigured method list can silently allow access. Test each action (GET/POST/PUT/DELETE) independently. (Details: Backend Documentation §9 & §18.)
6.4 Application-level entitlements¶
Access is also gated at two higher levels:
| Level | Controls | Set where |
|---|---|---|
| Company entitlement | Which apps a company may use (TOM / JE / LBT / …) | When the company is created/edited |
| User entitlement | Which of those apps a user may enter, and their scope/role in each | When the user is created/edited (TOM & JE tabs, plus the LBT and Dashboard switches) |
6.5 Restrictions (examples found in code)¶
| Restriction | Where |
|---|---|
| Some roles cannot access AI Insights | TOM frontend (rolesThatCantAccessAiInsights) |
| Certain data (Country/Currency lists) is publicly readable | Backend (no auth on those endpoints — see §15 security note) |
| "Global" (all-country) data creation is restricted to master/admin roles | Compensation module |
Job Grade Definitions & Job/PayNet libraries are limited to TOM_MASTER_USER |
JE app |
| Company users can only act within their own company | IsAdminOrOwnCompany check |
7. System Overview¶
7.1 The whole system in one picture¶
flowchart TB
subgraph "Frontend — 5 web apps (React)"
SSO[SSO Portal<br/>login + admin]
TOM[TOM<br/>offers + pay data]
JE[JE<br/>job evaluation]
LBT[LBT<br/>benchmarking]
DASH[Dashboard<br/>analytics]
end
subgraph "Backend — one system (Django)"
API[REST API<br/>/api/...]
end
DB[(PostgreSQL<br/>database)]
REDIS[(Redis<br/>queue + cache)]
WORKERS[Background workers<br/>Celery]
S3[(AWS S3<br/>files & reports)]
EXT[External services:<br/>OpenAI, Groq, Currency,<br/>Stock, Email]
SSO & TOM & JE & LBT & DASH -->|HTTPS + token| API
API --> DB
API --> REDIS
REDIS --> WORKERS
WORKERS --> DB
WORKERS --> S3
WORKERS --> EXT
API --> EXT
API --> S3
7.2 Plain-English component descriptions¶
| Part | What it is (plain English) | Technology |
|---|---|---|
| Frontend | The websites users click around in. There are five separate web apps that share one login. | React + TypeScript (Create React App), Redux, Ant Design + MUI |
| Backend | The "brain" — one system that all five apps talk to. It holds the rules and the data. | Python + Django + Django REST Framework |
| Database | Where all the data is stored permanently. | PostgreSQL |
| Queue & Cache (Redis) | A waiting line for slow jobs, and a short-term memory for speed. | Redis |
| Background workers | Do slow jobs (big reports, AI exports, emails) without making the user wait. | Celery |
| File storage | Where uploaded files, generated reports, logos, and PDFs live. | AWS S3 |
| External services | Outside tools the product uses (AI, currency rates, stock prices, email). | OpenAI, Groq, currency & stock APIs, Office365 email |
7.3 How the frontend apps relate¶
All five apps are built from the same template and talk to the same backend. They differ in which screens are active:
| App | Built on | Distinctive feature |
|---|---|---|
| SSO | Its own build (adds login forms) | The only app with a real login screen |
| TOM | The full template | Offer builder + all pay data + AI |
| JE | A newer build (React 18, deployed on Firebase) | Job evaluation + libraries |
| LBT | A trimmed copy of TOM | Benchmarking wizard only |
| Dashboard | A trimmed copy of TOM (adds charts) | Analytics charts |
📎 Deeper technical detail lives in the companion Backend Documentation. This handbook summarizes and references it rather than repeating it.
8. Data Flow¶
8.1 A typical user action, end to end¶
sequenceDiagram
participant U as User (in a web app)
participant FE as Frontend app
participant Cookie as Shared cookie
participant API as Backend API
participant SVC as Business logic
participant DB as PostgreSQL
U->>FE: Clicks "Save" (e.g. create an offer)
FE->>Cookie: Read identity token
FE->>API: HTTPS request with token (Bearer)
API->>API: Check identity + permissions
API->>SVC: Validate + apply business rules
SVC->>DB: Read/write data (in a safe transaction)
DB-->>SVC: Result
SVC-->>API: Result
API-->>FE: Standard response envelope (success, message, data)
FE-->>U: Screen updates
8.2 A slow job (report / AI export / email)¶
sequenceDiagram
participant U as User
participant API as Backend API
participant Q as Redis queue
participant W as Background worker
participant S3 as File storage
participant Mail as Email
U->>API: "Generate report"
API->>Q: Queue the job, return immediately
API-->>U: "Your report is processing..."
Q->>W: Worker picks up the job
W->>W: Do the heavy work
W->>S3: Save the finished file
W->>Mail: Send "your report is ready"
Note over U: The screen polls until status = Completed,<br/>then offers a download link
8.3 The standard response format¶
Every backend response uses the same shape, so all apps handle results consistently:
json
{
"success": true,
"message": "Human-readable message",
"code": 0,
"data": { },
"error": { },
"is_validation_error": false,
"is_paginated": false,
"pagination": { }
}
- success — did it work?
- message — a message to show the user.
- data — the actual result.
- error / is_validation_error — what went wrong, if anything.
- pagination — for long lists shown a page at a time.
9. Business Rules¶
Grouped by module. These are rules the system enforces.
9.1 Company & Access¶
- A company must exist before any pay data, users, or offers can be created.
- Creating a company auto-creates a Company Super User and emails a one-time password.
- Company name, contact email, and phone must be unique.
- A user's app access, scope, and role are set per application (TOM, JE), plus switches for LBT and the TOM Dashboard.
- Company users can only act within their own company.
9.2 Compensation Data (TOM)¶
- Every dataset is versioned; only one version is active per company per dataset.
- Uploading new data creates a new version and deactivates the previous one.
- Data can be global (all countries) or country-specific; global creation is restricted to master/admin roles.
- Deleting reference data is blocked if it's still used by active sub-items, offers, or job evaluations.
9.3 Offers (TOM)¶
- Offer statuses: Drafted → Placed → Accepted / Rejected, and Edited on revision.
- Only Placed offers can be revised; revising archives the current offer as a new version and marks the original Edited.
- Only Draft offers can be deleted.
- The offer's company job function must be mapped to a standard catalog function.
- Compensation totals (compa-ratio, target total cash, total remuneration) are calculated by the system, not entered by hand.
9.4 Job Evaluation (JE)¶
- Two evaluation models: Financial and Non-financial (they use different responsibility factors).
- Lifecycle: open → evaluated → close; a closed evaluation is locked (no edits).
- The score is derived from a fixed factor-scoring matrix, then mapped to a grade band.
9.5 Benchmarking (LBT)¶
- Reports are generated in the background and status-tracked.
- Small samples are suppressed (minimum companies/observations per statistic) — but a company always sees its own data.
- Custom peer baskets require at least 10 companies.
- Individual "by title" reports are limited by a per-company quota.
- If too few peers match, the user is prompted to expand the industry scope.
9.6 Grading¶
- Three related grading concepts coexist: TA rank mapping (JE), grade-point ranges (job grades), and grade scope (per user). (Engineers: these are not yet unified — see §13.)
10. Validation Rules¶
10.1 Field & form validations (examples)¶
| Area | Validation |
|---|---|
| Login | Email + password required (SSO uses form validation) |
| Company create | Name, address, HQ country, financial year, contract dates, logos, country, currency required; unique name/email/phone |
| User create | Name, email, phone required; at least one grade in scope unless Super User or JE-only |
| Offer | Grade + country must belong to the company; reporting grade must exist; job function must be mapped |
| Job evaluation | All factor questions required to run an evaluation |
| Password reset | Reset token must be valid and unexpired |
10.2 CSV upload validations¶
When a pay dataset is uploaded, the system runs it through a series of checks. If any check fails, the whole upload is rejected.
flowchart TB
U([User uploads a CSV]) --> C1{No missing<br/>required values?}
C1 -->|No| FAIL
C1 -->|Yes| C2{No duplicate<br/>rows?}
C2 -->|No| FAIL
C2 -->|Yes| C3{Valid dropdown<br/>enum values?}
C3 -->|No| FAIL
C3 -->|Yes| C4{Numbers & dates<br/>valid?}
C4 -->|No| FAIL
C4 -->|Yes| C5{Countries, currencies,<br/>grades exist?}
C5 -->|No| FAIL
C5 -->|Yes| C6{User allowed to<br/>touch this data?<br/><i>within their scope</i>}
C6 -->|No| FAIL
C6 -->|Yes| OK
FAIL[❌ Reject upload<br/>Send error email<br/>listing the problems]
OK[✅ Create new active version<br/>Deactivate old version<br/>Send success email]
10.3 Permission & access validations¶
- Every request must carry a valid identity token (except a few public endpoints).
- The user's role must hold the permission for the action.
- The user's scope must include the data being accessed.
- Company users are confined to their own company.
10.4 Error scenarios & how the system responds¶
| Scenario | System response |
|---|---|
| Wrong password | Generic "invalid credentials"; after 5 failures the account locks for 15 minutes |
| Too many login attempts | Login throttled (10/min per email) |
| Too many password-reset requests | Throttled (3 per 2 hours) |
| Expired/invalid token | The app silently refreshes the token; if that fails, it sends the user back to the login portal |
| Not enough benchmarking data | Report rejected with a clear "not enough data" message |
| Not permitted | 403 "unauthorized" in the standard envelope |
| Anything unexpected | Standardized "something went wrong" (500) with a safe message |
Login attempt & account-lockout flow:
flowchart TB
L([Login attempt]) --> LOCK{Account<br/>locked?}
LOCK -->|Yes| MSG[Show 'locked, try again<br/>in N minutes']
LOCK -->|No| PW{Correct<br/>password?}
PW -->|Yes| RESET[Reset failed-attempt counter] --> OK([Logged in])
PW -->|No| INC[Increase failed-attempt counter]
INC --> FIVE{5 or more<br/>failures?}
FIVE -->|Yes| DOLOCK[Lock account for 15 minutes] --> MSG
FIVE -->|No| INV[Show 'invalid credentials']
Expired-token auto-refresh flow (handled by the frontend):
flowchart TB
R([Request returns 'invalid token']) --> HAS{Have a valid<br/>refresh token?}
HAS -->|Yes| REF[Silently get a new access token] --> RETRY[Retry the original request] --> DONE([User never notices])
HAS -->|No| CLR[Clear stored login] --> SSO([Redirect to the Sign-in Portal])
11. Integrations¶
External systems the product depends on.
| Integration | Purpose | Data exchanged | Business impact if it fails |
|---|---|---|---|
| AWS S3 (file storage) | Store uploads, generated reports, logos, offer PDFs | Files in/out | Reports/uploads/PDFs unavailable; report jobs marked "error" |
| OpenAI | AI job-function mapping; offer-analysis summaries | Job/offer data → AI; suggestions back | AI mapping/summaries degrade to fallbacks or are skipped |
| Groq | AI compensation-insight messages | Offer/pay data → AI; insight text back | Falls back to predefined messages |
| Currency API (FastForex/exconvert) | Convert money between currencies | Currency codes → exchange rate | ⚠️ Currently returns a rate of 1.0 on failure — can silently produce wrong numbers (flagged for fixing) |
| Stock API (MarketStack) | Fetch stock prices for equity/stock tracking | Stock symbol → price | Stock values can't update; may error during company setup |
| Office365 Email (SMTP) | Send all transactional emails (one-time passwords, resets, upload results, report-ready) | Email content out | Users don't receive passwords/links/notifications |
| Prometheus | System monitoring metrics | Metrics out | Reduced observability only |
💡 Callout — how the apps connect to the backend. All five frontend apps talk to the backend over HTTPS using a token. They use environment settings (
REACT_APP_BASE_URL,REACT_APP_SSO_URL,REACT_APP_COOKIES_DOMAIN, and per-app URLs) that are filled in per environment. The exact production URLs are injected at deploy time and are not stored in the code.
12. Testing Perspective¶
12.1 Critical workflows (test these first)¶
- SSO login + app hand-off — log in once, move between TOM/JE/LBT/Dashboard without re-login; token refresh; logout clears everything.
- Company creation → super user email → first login → password reset.
- User provisioning — grant/deny each app, set scope and role, verify the user sees only what they should.
- Offer lifecycle — Draft → Place → Accept/Reject → Revise; email/PDF preview; totals correctness.
- Compensation data upload — valid and invalid CSVs for every dataset; versioning (new version becomes active, old preserved).
- Job evaluation — full questionnaire → correct grade result → submit locks it.
- Benchmarking report — wizard → background processing → completion email → CSV download; "not enough data" and peer-basket rules.
- Dashboards — filters and date ranges produce correct charts.
12.2 High-risk areas (extra scrutiny)¶
| Area | Why it's risky |
|---|---|
| Compensation calculations | The offer math exists in three places that can disagree (offer list, email/PDF, comparison). Verify they match. |
| Permissions | The "method not guarded → allowed" behavior means each verb must be tested separately; misconfig can silently over-grant. |
| Cross-tenant isolation | Some endpoints fetch by ID without confirming company ownership — test that users cannot access another company's data. |
| Version activation | Switching the active version must change what's read everywhere. |
| Currency conversion | Silent 1.0 fallback can produce wrong money without any error. |
| CSV edge cases | Encodings, duplicates, missing columns, out-of-scope references. |
| Background jobs | Report/AI-export failure handling, status transitions, idempotency. |
12.3 Important validations to regression-test¶
- Uniqueness (company name/email/phone; grades; user scope requirements).
- CSV validation suite (missing values, duplicates, enums, numeric/date, existence checks).
- Offer status transition rules (revise only when Placed; delete only when Draft).
- Job-evaluation "all factors required" and "locked when closed."
- LBT quota, suppression thresholds, and peer-basket ≥10 rule.
12.4 Smoke-testing checklist (quick post-deploy sanity)¶
- [ ] SSO login works; app picker shows the right apps.
- [ ] Open TOM, JE, LBT, Dashboard without re-login.
- [ ] Create a company (internal admin); super user gets an email.
- [ ] Add a company user; log in as them; scope respected.
- [ ] Upload one CSV (valid) — becomes active; download it back.
- [ ] Build and place one offer; preview email/PDF.
- [ ] Run one job evaluation to a grade result.
- [ ] Generate one benchmarking report to completion.
- [ ] Load one dashboard with filters.
- [ ] Trigger a validation error and confirm a clear message.
12.5 Known bug hot-spots (from code review)¶
These were identified in code and are worth targeted testing / fixing (details in Backend Documentation §18):
- Certain CSV uploads run their processing twice.
- A custom-job delete is broken (missing parameter).
- Job-evaluation submit writes fields that don't exist.
- A job-grade delete can remove rows across all companies.
- Some benchmarking aggregate stats can use the wrong grade's data.
13. Technical Overview¶
This is a summary for developers. It does not repeat the deep detail — see the companion Backend Documentation for models, endpoints, and internals.
13.1 Architecture at a glance¶
- Frontend: 5 React + TypeScript single-page apps (Create React App, Redux Toolkit + RTK Query for data, Ant Design + MUI for UI, React Router v5). They share a common template and a common REST wrapper (
tomService) that attaches the auth token, auto-refreshes it, handles CSV downloads, and redirects to SSO on auth failure. - Backend: a single Django + Django REST Framework "modular monolith" — one deployable project split into ~20 apps by domain. Layering is View → Serializer → Service → ORM. Background work runs on Celery + Redis. Data is in PostgreSQL. Files are in AWS S3.
- Auth: JWT tokens issued by the backend; shared across frontend apps via a browser cookie on a common domain (that's the SSO mechanism). Per-app access is confirmed via
/v2/auth/verify-user.
13.2 Major components¶
| Layer | Components |
|---|---|
| Frontend apps | sso-cicd, tom-cicd, taref-cicd (JE), live-bm-cicd (LBT), dashboard-cicd |
| Backend domains | authentication, company setup, compensation, offer modeler, job evaluations, job grades, grade, benchmarking, CSV uploader, AI (2 apps), dashboard, custom jobs, admin, applications, plus shared infra (response, exceptions, services, utils) |
| Data & infra | PostgreSQL, Redis, Celery workers, AWS S3 |
| External | OpenAI, Groq, Currency API, Stock API, Office365 SMTP, Prometheus |
13.3 Folder organization (high level)¶
- Frontend (each app):
src/pages(screens),src/router(routes + permissions),src/services(API calls),src/store(Redux state),src/components,src/constants. - Backend: one folder per domain app (
models.py,views.py,urls.py,serializers*.py, oftenservices/), plustombackend/(settings, URLs, Celery) and shared folders (services/,response/,tom_exceptions/,utils/).
13.4 API organization¶
- All backend endpoints live under
/api/…. Auth is the only versioned area (/api/auth/and/api/v2/auth/). - Company-scoped endpoints follow the pattern
/api/company/<company_id>/…. - Full endpoint catalog: Backend Documentation §7.
13.5 Database overview¶
- ~100+ tables in PostgreSQL. The signature pattern in the compensation domain is Version + Data + child-scoping tables, with exactly one active version per company per dataset.
- Most records use a soft-delete convention (an
is_activeflag) rather than hard deletion. - Full model/relationship detail: Backend Documentation §8.
13.6 Deployment (from code)¶
- Backend runs under Gunicorn with Celery workers (managed by Supervisor), deployed via AWS CodeDeploy hooks; containerized with Docker.
- Frontends build via AWS CodeBuild (and JE additionally has Firebase deploy config).
- Environment-specific settings are chosen by an
envvariable and injectedREACT_APP_*values at build time.
14. Glossary¶
| Term | Plain-English meaning |
|---|---|
| Allowance (Cash Allowance) | Extra cash paid on top of base salary (e.g., housing, transport). |
| Application (App) | One of the five tools in the platform (SSO, TOM, JE, LBT, Dashboard). |
| Backend | The central "brain" system that stores data and enforces rules. |
| Base salary / Base pay | The fixed regular salary, before bonuses or extras. |
| Benchmarking | Comparing pay against the market. |
| Benefit Plan | Non-cash or structured benefits (health, wellness, etc.). |
| Business Unit | A division or department within a company. |
| Celery / Worker | The part of the system that does slow jobs in the background so users don't wait. |
| Company / Tenant | A client organization. All data belongs to one company. |
| Compa-Ratio | A person's pay divided by the market/mid-point for their grade. ~1.0 means "paid at market." |
| Cookie | A small piece of data the browser stores; here it carries the shared login between apps. |
| CSV | A spreadsheet file format used for bulk upload/download. |
| Dashboard | A screen of charts and KPIs. |
| Equity / LTI (Long-Term Incentive) | Pay in company shares/options, usually vesting over years. |
| Frontend | The websites/apps users click around in. |
| Grade | A seniority level for a job; pay is usually defined per grade. |
| JE (Job Evaluation) | The process/app that scores a job and assigns it a grade. |
| JWT (Token) | A secure digital "pass" proving who you are on each request. |
| LBT (Live Pay Benchmarking Tool) | The app that generates market pay reports. |
| Legal Entity | A registered company entity within a country (for payroll/legal purposes). |
| Market Data | Salary survey/market pay figures used for comparison. |
| Offer | A proposed pay package for a candidate. |
| One-Time Password (OTP) | A temporary password emailed to a new user; must be changed on first login. |
| Payroll (Internal Payroll) | The company's actual employee pay records. |
| Peer Basket | A custom set of companies chosen to compare against in benchmarking. |
| Percentile (p25/p50/p75…) | Where a value sits in a distribution; p50 is the median. |
| Permission | The right to perform a specific action. |
| PostgreSQL | The database that stores all data. |
| RTK Query | The frontend tool that fetches data from the backend. |
| Redis | Fast temporary storage used for the job queue and caching. |
| Role | A named bundle of permissions (e.g., Company Admin). |
| S3 | Amazon's cloud file storage. |
| Scope (Row-level scope) | The specific slice of data a user is allowed to see. |
| SSO (Single Sign-On) | Logging in once and moving between apps without logging in again. |
| STI (Short-Term Incentive) | Annual bonus-type pay. |
| TDC / TGC / TR / TTC | Total Direct Compensation / Total Guaranteed Cash / Total Remuneration / Target Total Cash — different ways of summing up pay. |
| TOM | Total Offer Management — the main compensation & offer app. |
| Version | A saved snapshot of data; only one is active at a time. |
15. Frequently Asked Questions¶
For new employees¶
Q: What does this company's product actually do? It helps companies decide and deliver employee pay — set up pay structures, evaluate job seniority, build competitive offers, benchmark against the market, and analyze pay fairness.
Q: There are five apps — do I need to learn all of them? No. Most work happens in TOM (offers & pay data). JE is for job evaluation, LBT for benchmarking, Dashboard for analytics, and SSO is just the login/admin front door.
Q: Why do I only see some apps? Because access is granted per company and per user. You see what you've been entitled to.
For business users¶
Q: Do I log in separately for each app? No — you log in once in the Sign-in Portal (SSO) and move between apps freely.
Q: I forgot my password. Use "Forgot Password" on the login screen. You'll get a reset link (valid for a short time). Too many attempts will temporarily lock the request.
Q: I uploaded a CSV and nothing happened / I got an error email. The file failed validation. The error email lists exactly what was wrong (missing values, duplicates, invalid options, etc.). Fix and re-upload.
Q: Why can't I see some data? Your access scope (business units, regions, countries, grades, functions) limits what you can see. Ask your company admin to widen your scope if needed.
For QA engineers¶
Q: What are the riskiest things to test? Compensation calculations (three implementations can differ), permission behavior (each action gated separately), cross-company data isolation, version activation, currency conversion (silent fallback), CSV edge cases, and background-job handling. See §12.
Q: Where do I find the exact business rules and validations? Sections 9 and 10 here; deeper detail in Backend Documentation §9–§15.
Q: Are there known bugs? Yes — see §12.5.
For developers¶
Q: Where's the deep technical documentation? The companion Backend Documentation (19 sections: architecture, modules, endpoints, DB, auth, background jobs, integrations, performance, security, code review). This handbook summarizes it.
Q: How does login/SSO work technically?
The backend issues JWT tokens. The SSO app stores them in a cookie on a shared domain; other apps read that cookie and call /v2/auth/verify-user to confirm access for their specific app. The frontend tomService wrapper auto-refreshes expired tokens and redirects to SSO on failure.
Q: How do the frontend apps relate? They share one template and one backend. TOM is the full app; LBT and Dashboard are trimmed copies; JE is a newer build; SSO adds the login/management screens.
Q: Where do I add a new feature?
Frontend: a page in src/pages, a service in src/services, state in src/store, a route in src/router. Backend: a view + serializer + service + URL in the relevant app. See Backend Documentation §17.
For product managers¶
Q: What's the core workflow I should understand? Company is created → apps are granted → users are provisioned → pay data is set up → jobs are evaluated (grades) → offers are built → benchmarking & dashboards inform decisions. See §4.
Q: What are the product's differentiators? Structured, versioned pay data; a guided offer builder with AI insights; objective job evaluation; live market benchmarking; and pay-fairness analytics — all multi-tenant and permission-scoped.
Q: What are the biggest current risks/limitations? Duplicated compensation math, some permission/scoping gaps, silent currency-conversion fallback, and several known bugs — all documented in §12 and Backend Documentation §18–§19.
Appendix — What could NOT be determined from the code¶
To stay honest, these items are not derivable from the codebase and should be confirmed with the team:
- Exact production URLs for each app and the shared cookie domain — these are injected at deploy time, not stored in code.
- The live backend base URL(s) used by each frontend environment.
- Whether Sentry error tracking is actually wired up (a flag exists but no setup was found).
- The production cache backend configuration (assumed Redis, not explicitly defined in the settings read).
- Any business processes that happen outside the software (manual approvals, contracts, commercial terms).
For anything above, the correct answer is: "Unable to determine from the available code."
This handbook was assembled from a full review of the frontend (5 React apps) and backend (Django) source code. It is a living document — update it as the product evolves. For engineering-depth questions, start with the companion Backend Documentation.