---
apiVersion: data-spec/v1
id: quote-product-custom-object-quarantine-20260425
description: "Reclassify legacy quote_product__c metadata from standard_object to custom_object after moving its authoring source into the PingCAP tenant quarantine"
issue: "#2019"
created: 2026-04-25
scope: production-only
status: pending
tables: [_System_Object, _System_Table]
depends_on: []
---

# Quote Product Custom Object Quarantine

## Summary

Issue #2019 moves `quote_product__c` out of
`backend/internal/controlplane/packspec/standard_objects_spec.json` and into
`backend/internal/controlplane/tenants/pingcap/tenant_objects_spec.json`.
Fresh greenfield orgs will no longer receive this tenant object from the
platform pack. Existing PingCAP orgs may still have rows that were created
while the object was incorrectly authored as `standard_object`.

This spec fixes that historical classification without dropping the physical
table and without touching user records. The tenant overlay remains the long
term authoring source; this data-spec is only for already-bootstrapped
metadata rows.

## Changes

### 1. Preflight

```sql
SELECT
  o.Id,
  o.ApiName,
  o.TableType AS object_table_type,
  o.IsCustom,
  t.TableType AS registry_table_type
FROM _System_Object o
LEFT JOIN _System_Table t ON t.TableName = o.ApiName
WHERE o.ApiName = 'quote_product__c';
```

Expected pre-apply state on affected upgraded orgs: one row with
`object_table_type='standard_object'` and `IsCustom=0`. Greenfield orgs that
never applied the PingCAP tenant overlay may return zero rows.

### 2. Apply

```sql
UPDATE _System_Object
SET
  TableType = 'custom_object',
  IsCustom = 1,
  LastModifiedDate = NOW()
WHERE ApiName = 'quote_product__c'
  AND (
    COALESCE(TableType, '') <> 'custom_object'
    OR COALESCE(IsCustom, 0) <> 1
  );

UPDATE _System_Table
SET
  TableType = 'custom_object',
  LastModifiedDate = NOW()
WHERE TableName = 'quote_product__c'
  AND COALESCE(TableType, '') <> 'custom_object';
```

**Idempotency**: re-running the spec updates zero rows once both metadata
surfaces already say `custom_object`.

**Preservation**: no `DROP`, `DELETE`, `TRUNCATE`, column rewrite, or table
rename. User data in `quote_product__c` is preserved.

### 3. Audit

```sql
SELECT
  o.ApiName,
  o.TableType AS object_table_type,
  o.IsCustom,
  t.TableType AS registry_table_type
FROM _System_Object o
LEFT JOIN _System_Table t ON t.TableName = o.ApiName
WHERE o.ApiName = 'quote_product__c'
  AND (
    o.TableType <> 'custom_object'
    OR COALESCE(o.IsCustom, 0) <> 1
    OR COALESCE(t.TableType, '') <> 'custom_object'
  );
```

Expected result after apply: zero rows.

## Rollback

Rollback is not recommended because the platform pack no longer owns this
object. If an operator must restore the exact pre-spec classification for a
point-in-time rollback, run:

```sql
UPDATE _System_Object
SET
  TableType = 'standard_object',
  IsCustom = 0,
  LastModifiedDate = NOW()
WHERE ApiName = 'quote_product__c';

UPDATE _System_Table
SET
  TableType = 'standard_object',
  LastModifiedDate = NOW()
WHERE TableName = 'quote_product__c';
```
