Skip to content

Compensation (Payroll & Benefits) schema

Current data contract for Payroll and Comp's ServiceNow-side tables, read directly from nova-compensation-sn-app's live fluent dictionary (sn_app/nova_src/fluent/dictionary/*.now.ts) on main. Reverse-engineered per the 2026-08-07 decision retiring schema/pending/ — goes directly here with status: applied, since this reflects real, committed, shipped code, not a proposal.

This app integrates with external payroll/benefits providers (Finch, Merge, Knit, Bindbee, plus a mock provider) rather than running payroll itself — most tables here are provider-synced mirrors (raw_payload, last_synced, source_provider on nearly every table), not a system of record Novaworks computes from scratch. Every table carries sys_domain (ServiceNow Domain Separation) — omitted from the entity blocks below for readability.

Diagram

erDiagram
    ProviderConnection }o--|| CorehrCompany : "company (cross-repo)"
    WorkerIdentity }o--|| CorehrWorker : "worker (cross-repo)"
    WorkerIdentity }o--|| ProviderConnection : "connection"
    EmployeeBenefit }o--|| CorehrWorker : "worker (cross-repo)"
    EmployeeBenefit }o--|| WorkerIdentity : "worker_identity"
    EmployeeBenefit }o--|| BenefitMaster : "benefit_master"
    BenefitMaster }o--|| ProviderConnection : "connection"
    PayGroup }o--|| CorehrCompany : "company (cross-repo)"
    PayGroup }o--|| ProviderConnection : "connection"
    PayrollRun }o--|| ProviderConnection : "connection"
    PayStatement }o--|| PayrollRun : "payroll_run"
    PayStatement }o--|| CorehrWorker : "worker (cross-repo)"
    PayStatement }o--|| WorkerIdentity : "worker_identity"
    PayStatement }o--|| PayGroup : "pay_group"
    PayStatementLine }o--|| PayStatement : "pay_statement"
    SyncRun }o--|| ProviderConnection : "connection"
    WorkerCompensation }o--|| CorehrWorker : "worker (cross-repo)"
    CompTransactionInstance ||--|| PlatformTransactionInstance : "extends (cross-repo)"

    ProviderConnection {
        string provider_code
        string company_name
        ref company
        ref credential
        ref auth_profile
        string external_connection_id
        string provider_company_id
        string customer_ref
        string status
        datetime connected_at
        datetime last_full_sync
    }

    WorkerIdentity {
        ref worker
        ref connection
        string source_provider
        string external_id
        string universal_worker_key
        datetime last_synced
    }

    BenefitMaster {
        string external_id
        ref connection
        string benefit_name
        string benefit_type
        string frequency
        string company_contribution_type
        string raw_payload
        datetime last_synced
    }

    EmployeeBenefit {
        ref worker
        ref worker_identity
        ref benefit_master
        ref connection
        decimal employee_deduction
        decimal employer_contribution
        string deduction_type
        string currency
        string status
    }

    PayGroup {
        ref connection
        string name
        string pay_frequency
        ref company
    }

    PayrollRun {
        ref connection
        string external_id
        string run_type
        date pay_period_start
        date pay_period_end
        date pay_date
        date debit_date
        string status
        decimal total_gross
        decimal total_net
        string currency
    }

    PayStatement {
        ref payroll_run
        ref worker
        ref worker_identity
        ref connection
        ref pay_group
        decimal gross_pay
        decimal net_pay
        decimal total_employee_taxes
        decimal total_employer_taxes
        decimal total_employee_deductions
        decimal total_employer_contributions
        decimal hours_worked
        string pay_type
        string payment_method
        string currency
    }

    PayStatementLine {
        ref pay_statement
        ref connection
        string line_type
        string category
        string name
        decimal amount
        string currency
        boolean pre_tax
        boolean is_employer
    }

    SyncRun {
        ref connection
        datetime started
        datetime finished
        string status
        int records_processed
        string message
    }

    WorkerCompensation {
        ref worker
        date effective_date
        date start_date
        date benefits_eligibility_date
        decimal base_salary
        decimal sign_on_bonus
        decimal equity_value
        int equity_units
        string pay_frequency
        string currency
    }

    CompTransactionInstance {
        string intent
    }

CompTransactionInstance (x_novaw_comp_transaction_instance) adds only an intent choice field (get_paycheck, get_benefits, query, unsupported) on top of x_novaw_platform_transaction_instance.

Cross-repo dependencies

  • ProviderConnection.company, PayGroup.companyx_novaw_corehcm_company.
  • EmployeeBenefit.worker, PayStatement.worker, WorkerCompensation.worker, WorkerIdentity.workerx_novaw_corehcm_worker.
  • x_novaw_comp_transaction_instance extends x_novaw_platform_transaction_instance (Platform domain — see specs-platform).
  • ProviderConnection.credential/auth_profile → native api_key_credentials/ sys_auth_profile (platform/global ServiceNow tables, not Novaworks-owned).

Core HR references are on tables already covered by core-hr-schema.md in this same repo. The Platform dependency is a genuine specs-corehrspecs-platform schema coupling, same pattern as EDM's and Onboarding's transaction_instance extension.

Discrepancies vs. github-private's component KB

github-private/docs/profile/repos/nova-compensation-sn-app/tables.md is meaningfully behind the live code in several places: - Frames ProviderConnection as Finch-only; code's provider_code choice has 5 values (finch, merge, knit, bindbee, mock). - BenefitMaster.external_benefit_id (tables.md) vs. live external_id; benefit_type choice list in tables.md has only 4 of the code's 8 values. - PayStatement.taxes_withheld (tables.md) doesn't exist in code — actual fields are total_employee_taxes/total_employer_taxes/ total_employee_deductions/total_employer_contributions. - PayStatementLine.line_type choice values and the description field name in tables.md don't match code (code: earning/tax/ employee_deduction/employer_contribution; field is name, not description). - WorkerCompensation.equity (tables.md) vs. live equity_value (+ separate equity_units). - x_novaw_comp_transaction_instance isn't mentioned in tables.md at all. - WorkerIdentity, SyncRun, and PayGroup are documented in tables.md as near-empty stubs; code has full field sets for all three.

Open items

  • None beyond the tables.md staleness noted above — no unresolved modeling questions surfaced in this pass.