---
id: TST-PFM-MTD-110
title: custom fields table
kind: integration
product_area: platform
module: metadata
revision: 1
status: draft
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
repository: services-platform
files:
  - modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js
implements:
  - ATS-PFM-MTD-005-01
environment: local
implementation_state: implemented
latest_result: not-run
latest_run_at: null
latest_run_ref: null
conformance: not-verified
estimated_minutes: 5
isolation: >-
  Prepared integration database and the suite fixture records; fixture teardown restores or removes its own
  rows.
evidence:
  - 'services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js'
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    second row with the same tenant, object and key by custom_fields_pk
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    key that is not a custom key by custom_fields_key_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    data type outside the closed list by custom_fields_data_type_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    display outside the closed list by custom_fields_default_display_type_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    string's length on another data type by custom_fields_string_configuration_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    numeric bound on another data type by custom_fields_bounds_configuration_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses
    integer choices on another data type by custom_fields_integer_configuration_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    boolean's labels on another data type by custom_fields_boolean_configuration_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses
    accepted media types on another data type by custom_fields_file_configuration_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses
    decimal places on another data type by custom_fields_decimal_places_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    list without its option arrays by custom_fields_list_configuration_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses
    list option ids and labels of different lengths by custom_fields_list_options_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    reference without a target object by custom_fields_target_object_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    lock that is not one of the two it allows by custom_fields_sys_locked_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    tenant that does not exist by custom_fields_tenant_fk
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#accepts an
    object id with no row in the registry, because liveness is the write path’s (migration
    custom_object_definitions)
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#accepts a
    reference target with no row in the registry, a custom object’s id among them
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#accepts a
    plain key on a custom object, by the first rule of custom_fields_key_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses
    the __c suffix on a custom object, by custom_fields_key_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    plain key on a registered object, by the second rule of custom_fields_key_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    group label over 100 characters, by custom_fields_group_label_check
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#stores a
    blank group label as null, by the normalisation trigger
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    row with no label
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses a
    row with no creator
  - >-
    services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#leaves no
    row behind after a refused insert
fixture_imports:
  - drizzle-orm
  - ../../../db/custom-fields.table
  - '@rhythmsoftware/macroservice-testing/refusals'
  - '@rhythmsoftware/macroservice-errors/pg-errors'
  - ../support
test_doubles: []
limitations: []
unmatched_specification: null
binding_assertions:
  - scenario: ATS-PFM-MTD-005-01
    provenance: test
    source:
      - >-
        services-platform:modules/metadata/tests/integration/db/custom-fields.table.integration.spec.js#refuses
        a plain key on a registered object, by the second rule of custom_fields_key_check
    note: >-
      These references identify the assertions this suite contributes; bindings to additional suites remain
      part of the scenario’s proof.
---

# Custom fields table

## Verification Boundary

This integration suite checks record descriptions and field configuration within the local test harness. The registered file and pinned revision define its boundary.

## What This Suite Proves

The bindings identify the detailed or feature scenarios whose outcomes have assertions in this suite. Original case references remain attached to the detailed scenarios so a reviewer can inspect the exact assertion. Assertions are evidence of implemented checks; no execution result is claimed.

## What It Does Not Prove

The register does not establish a current passing run or full specification conformance. Behavior outside the suite’s fixtures and assertions remains unverified.

## Real Dependencies and Test Doubles

The fixture uses PostgreSQL and the imported persistence or API code. The fixture imports identify the setup seams; this register makes no broader claim that dependencies are undoubled.

## Must Not Be Doubled

The operation under examination and its asserted stored outcomes must remain real within the declared harness. A fixture cannot replace the write, refusal or transactional effect that the bound scenario checks.
