Rails-owned table ownership map
rulebase-api2/src/db/rails-schema.ts declares 166 public.* tables that
Rails owns. Every declaration is a persistence dependency that keeps API2
coupled to Rails DDL and, for many tables, to Rails write paths. This page
classifies each table and sequences the work to make API2’s persistence
independent.
Methodology
For each declared table we measured, on origin/main (2026-09-09):
- API2 files — files importing the table’s
rails*const fromsrc/db/rails-schema.ts, plus files with raw SQL touchingpublic.<table>. Note that several api2 files import api2-native tables aliased asrailsXfromsrc/db/schema.ts(e.g.dashboards as railsDashboards); those are not public-schema dependencies and were excluded. - API2 ops — Drizzle
insert/update/deletecalls and rawINSERT INTO/UPDATE/DELETEagainst the table. - Rails refs / Rails write files — files under
rulebase-api/app|libreferencing the classified model class, and files containingModel.create/insert_all/upsert/find_or_createwrite calls.
Static analysis cannot see callbacks, acts_as_tenant associations,
after_commit hooks, or writes issued through save/update on fetched
records, so Rails write evidence is a floor, not a ceiling. Treat
“Rails-coupled” (a live model exists) as dual-written until the write paths
are verified — the safe default is to assume both services can write.
Classes
| Class | Meaning |
|---|---|
| Read-only projection | API2 only reads; Rails is the sole writer. |
| API2 writer | API2 writes; no Rails model or write path found. |
| Rails writer | API2 does not write; Rails writes (API2 may read). |
| Dual-written | Both services have write paths — or API2 writes while a live Rails model couples the table (callbacks/associations make the table unsafe to move until verified). |
| Retirement candidate | Dead table or dead declaration: neither service needs it, or API2’s copy already owns the data. |
| Framework | Gem/framework-owned (flipper_*, active_storage_*, pg_search_documents); never migrates. |
Summary
| Class | Tables |
|---|---|
| Dual-written (incl. Rails-coupled api2 writes) | 107 |
| Rails writer (API2 read-only) | 44 |
Retired in this PR (deprecated_dashboard_*) | 8 |
| Framework | 5 |
Rails-owned live catalog (dashboard_widget_types, dashboard_widget_type_groups) | 2 |
| Total declared | 166 |
After this PR the declared surface drops to 156 tables.
Domain ranking: traffic Ă— coupling
Traffic tier reflects request-path reads and ingest-write volume (structural
signals: api2 file coupling, write ops, and the GoodJob traffic evidence in
goodjob-traffic); each work package must confirm actual
production counts (pg_stat_user_tables, GoodJob execution counts) before
cutover. Coupling = dual-write or live-Rails-model surface.
| Rank | Domain | Tables | API2 writers | Dual-written | Tier | Why |
|---|---|---|---|---|---|---|
| 1 | Conversations (conversations, conversation_parts, part details, threads, assignments, tags) | 29 | 24 | 24 | T0 — ingest path | Highest volume; every provider sync and UI read hits these. |
| 2 | QA & evaluations (qa_agent_evaluations, scorecard results, evaluation batches/contests, scorecards) | 32 | 21 | 21 | T0 — QA pipeline | Fan-out per conversation × criterion; heaviest per-row write volume. |
| 3 | Identity & access (organizations, accounts, memberships, roles, workspaces, api_keys) | 13 | 11 | 11 | T0 — every request | Read on nearly every authenticated call; writes are rare but auth-critical. |
| 4 | Integrations & sync (organization_data_sources, data_sources, zendesk_*, jira_*, slack_*) | 16 | 12 | 12 | T0 — sync path | Provider webhooks/polls write continuously. |
| 5 | Workforce (employees, teams, groups, partners, work_schedules) | 9 | 6 | 6 | T1 | Directory reads everywhere; writes are admin/sync driven. |
| 6 | Knowledge base (knowledge_base_*) | 4 | 4 | 4 | T1 | API2 sync worker is primary writer; Rails reads. |
| 7 | Customers & complaints (customer_*, complaint*) | 10 | 4 | 4 | T1 | Moderate volume. |
| 8 | Sheets & tests (sheets, sheet_*, test_*, cell_*) | 7 | 7 | 7 | T1 | API2 writes; Rails models remain for sheet surface. |
| 9 | CRM & clients (clients, client_integration_profiles, disputes) | 3 | 3 | 3 | T1 | Compliance-adjacent writes. |
| 10 | Compliance (compliance_*, audit_events, frameworks) | 7 | 1 | 1 | T2 | Mostly Rails-written reporting. |
| 11 | SLA & schedules (sla_policies, conditions, targets) | 3 | 0 | 0 | T2 | Config; Rails-written. |
| 12 | Notifications & digests | 3 | 1 | 1 | T2 | Low volume. |
| 13 | Billing (credits) | 1 | 1 | 1 | T2 | Low volume, sensitive. |
| 14 | Framework (flipper_*, active_storage_*, pg_search_documents) | 5 | 3 | 0 | T0 I/O but infra-owned | Never migrate; API2’s flipper/active-storage reads are intentional shared-infra use. |
| 15 | Dashboards (public.dashboard_*) | 10 | 0 | 0 | Dead | Retired/kept-catalog — see below. |
Retired in this PR: public.dashboard_* instance tables
Evidence for retirement:
- Rails deleted all custom-dashboard models, controllers, blueprints, and
factories in #7095 (2026-05-30). Only the widget-type catalog
(
dashboard_widget_types,dashboard_widget_type_groups) remains live in Rails routes. - API2 dashboard code uses only the
api2.dashboard_*copies created and backfilled by drizzle migration0060. TherailsDashboard*names insrc/routes/dashboards.tsandsrc/lib/homepage-dashboard.tsalias api2-native tables, not the public ones. - Zero api2 imports of the public-table consts; zero raw SQL touches
public.dashboard_*; all FKs are intra-family (verified live — no FK from outside the set points into it).
Shipped here:
rulebase-apimigration20260909225243_deprecate_legacy_dashboard_tablesrenames the 8 dead instance tables todeprecated_dashboard_*— a forward-only, non-destructive, instantly reversible cut (rename back on rollback).safety_assuredis justified in-file: no code references the tables, so nothing live can break; any hidden consumer fails fast instead of reading stale data.- All 10 dead
rails*declarations removed fromsrc/db/rails-schema.ts(the two catalog consts too — API2 never used them; the catalog stays Rails-owned). scripts/verify-rails-table-retirement.ts(pnpm db:verify-table-retirement(:local|:infisical)) — read-only audit that a table set is dead in code and in the expected physical state; reusable for every package below.
No runtime flag is needed: the change removes no live behavior. The flag
equivalent is the staged rollout itself — rename now, observe, drop later.
Rollback: db:rollback (or a follow-up rename migration per the
forward-only rule). Follow-up: after a ≥2-week bake with no Sentry
noise, drop deprecated_dashboard_* in a second migration; re-run the
verifier with --expect=absent first.
Known blind spot (pre-merge sign-off): confirm no BI/warehouse or data-sync
job reads public.dashboard_* — external consumers are not visible in the
repo.
Work packages
Each package is a sequence of PR-sized steps following the existing package
convention: API2 takes writes behind a PostHog rollout flag (fail-closed) or
Flipper kill switch where safe-state-on applies, with an
outbound_delivery_claims-style single-winner contract where Rails still
initiates. Generic steps per table family:
- Verify — production
pg_stat+ GoodJob counts; runpnpm db:verify-table-retirement/ write-path audit on both services. - Single writer — cut one write edge at a time behind a flag; keep dual-write or read-repair during the window.
- Backfill/reconcile — a reconciliation job or script; compare counts.
- Bake — observe ≥1 week at 100%; then remove the flag and the dead
path. Remove the
rails*declaration last.
WP-1 — zendesk_webhook_ticket_syncs (smallest true dual-write)
Rails ZendeskWebhook.record_event! inserts on ingest, then
ZendeskWebhookTicketSync#handoff_to_api2 hands off synchronously via
Api2ZendeskWebhookTicketSyncEnqueuer (no GoodJob since ENG-2506); API2
reads/updates/deletes rows and its recovery sweep re-arms stranded ones.
Target: API2 ingest creates and owns the rows; Rails stops inserting.
- PostHog
api2_owns_zendesk_webhook_ticket_syncs(owner: platform; review ≤90 days) gating the Rails insert; API2-side creates the row inside its enqueue path. - Rollback: flag off → Rails resumes creating rows; API2 already tolerates pre-existing rows.
WP-2 — QA result persistence (qa_agent_evaluations, qa_agent_evaluation_scorecard_results, qa_agent_evaluation_scorecard_criterion_results, ..._check_results, ..._check_kb_citations, ..._kb_citations, qa_evaluation_requests, evaluation_scorecard_criterion_result_comments)
API2 is the primary writer (QA agent pipeline); Rails keeps models for reads/serialization. Highest per-row volume after conversations.
- Per family: enumerate Rails write sites (mostly backfill/contest paths),
move each behind its own flag (
api2_owns_qa_*); Rails models convert to read-only. - Verify row parity per org before deleting any Rails write path.
WP-3 — Conversation ingest persistence (conversation_parts + detail tables, conversation_threads/thread_items, conversation_field_values, conversation_part_attachments, assignments, conversation_teams, tags, conversation_tags)
Highest-traffic domain; most dual-write edges. Split per part-type (attachments, notes, chat details, email details, call details, assignments) — each is its own flag-gated PR inside the package.
WP-4 — Provider config & catalog (organization_data_sources, data_sources, zendesk_brands, integrations, connections, jira_* catalog)
Mixed admin-write (Rails UI) + sync-write (API2). Requires an explicit write-arbitration decision per table before cutover — flag this to product if sync-time upserts conflict with admin edits.
WP-5 — Identity read graph (organizations, accounts, memberships, roles, permissions, membership_scopes, workspaces, api_keys, invitations, sessions, workos_* events)
Formalize as Rails-owned read-only projections: API2 never writes (the current raw writes are auth/session flows being ported — finish those ports under the native-session packages, then freeze). Do not move the tables.
WP-6 — Long tail (knowledge_base_*, sheets/test_*/cell_*, employees/teams/groups/partners, customers/complaints, clients, disputes, audit_events, SLA tables, credits, digests)
Same recipe per family, ordered by write volume measured in WP-1..4.
WP-7 — Never migrate
flipper_features/flipper_gates (shared kill-switch store, read via raw
SQL in src/lib/flipper.ts), pg_search_documents (pg_search gem),
active_storage_blobs/attachments (ActiveStorage), data_migrations,
schema_migrations, ar_internal_metadata, versions, and
dashboard_widget_types/dashboard_widget_type_groups (live Rails catalog).
Appendix: per-table classification
Rails refs/writes are heuristic file counts — a nonzero count means
“verify before touching”, zero means “no evidence found”. retired-this-pr
rows are renamed to deprecated_* by this PR’s migration.
| Table | Domain | Class | API2 files | API2 ops | Rails write files | Rails refs |
|---|---|---|---|---|---|---|
accounts | identity & access | Dual-written | 61 | raw-write | 4 | 69 |
active_storage_attachments | framework | Framework | 24 | delete,insert,raw-write | 0 | 0 |
active_storage_blobs | framework | Framework | 22 | delete,insert,raw-write | 0 | 0 |
agent_integration_profiles | agents & bots | Dual-written (Rails: model/reads only) | 18 | insert,raw-write,update | 0 | 16 |
agent_performance_report_citations | agents & bots | Dual-written (Rails: model/reads only) | 3 | raw-write | 0 | 1 |
agent_performance_reports | agents & bots | Dual-written | 7 | raw-write | 2 | 15 |
api_keys | identity & access | Dual-written (Rails: model/reads only) | 3 | raw-write,update | 0 | 4 |
assignment_queue_memberships | other | Dual-written (Rails: model/reads only) | 4 | insert,update | 0 | 5 |
assignment_queues | other | Dual-written (Rails: model/reads only) | 8 | insert | 0 | 10 |
audit_events | compliance | Dual-written | 7 | insert,raw-write | 2 | 6 |
call_script_guideline_steps | other | Rails writer | 1 | - | 0 | 2 |
call_script_guidelines | other | Rails writer | 1 | - | 0 | 4 |
cell_reasoning_citations | sheets & tests | Dual-written (Rails: model/reads only) | 2 | delete,insert | 0 | 2 |
client_integration_profiles | CRM & clients | Dual-written (Rails: model/reads only) | 2 | insert | 0 | 2 |
clients | CRM & clients | Dual-written | 49 | insert,raw-write,update | 14 | 93 |
companies | other | Dual-written | 43 | insert,raw-write,update | 6 | 20 |
company_field_values | other | Dual-written (Rails: model/reads only) | 6 | delete,insert,raw-write,update | 0 | 2 |
company_fields | other | Dual-written (Rails: model/reads only) | 10 | insert,raw-write | 0 | 8 |
complaints_jira_request_types | customers & complaints | Rails writer | 1 | - | 0 | 1 |
compliance_alerts | compliance | Rails writer | 2 | - | 2 | 5 |
compliance_cases | compliance | Rails writer | 2 | - | 2 | 8 |
compliance_criterion_groups | compliance | Rails writer | 5 | - | 2 | 9 |
compliance_rule_documents | compliance | Rails writer | 3 | - | 1 | 8 |
compliance_tests | compliance | Rails writer | 6 | - | 0 | 9 |
connection_logs | integrations & sync | Dual-written (Rails: model/reads only) | 2 | raw-write | 0 | 3 |
conversation_agents | conversations | Dual-written | 36 | insert,raw-write | 1 | 16 |
conversation_assignments | conversations | Dual-written | 3 | insert,update | 2 | 12 |
conversation_customer_sentiment_summaries | conversations | Rails writer | 8 | - | 1 | 8 |
conversation_customers | conversations | Dual-written (Rails: model/reads only) | 31 | insert,raw-write | 0 | 3 |
conversation_field_values | conversations | Dual-written | 28 | raw-write | 1 | 5 |
conversation_fields | conversations | Dual-written | 25 | insert,raw-write,update | 3 | 18 |
conversation_filters | conversations | Rails writer | 2 | - | 0 | 2 |
conversation_groups | conversations | Rails writer | 5 | - | 0 | 1 |
conversation_part_assignments | conversations | Dual-written (Rails: model/reads only) | 11 | raw-write,update | 0 | 6 |
conversation_part_attachments | conversations | Dual-written (Rails: model/reads only) | 13 | insert,raw-write,update | 0 | 6 |
conversation_part_attribute_updated_by_admins | conversations | Dual-written (Rails: model/reads only) | 10 | raw-write | 0 | 6 |
conversation_part_call_detail_transcript_messages | conversations | Dual-written (Rails: model/reads only) | 22 | raw-write | 0 | 13 |
conversation_part_call_details | conversations | Dual-written (Rails: model/reads only) | 31 | insert,raw-write | 0 | 28 |
conversation_part_chat_details | conversations | Dual-written (Rails: model/reads only) | 23 | insert,raw-write,update | 0 | 12 |
conversation_part_email_details | conversations | Dual-written (Rails: model/reads only) | 22 | insert,raw-write,update | 0 | 9 |
conversation_part_notes | conversations | Dual-written (Rails: model/reads only) | 19 | insert,raw-write,update | 0 | 7 |
conversation_partners | conversations | Dual-written | 11 | insert,raw-write | 1 | 3 |
conversation_parts | conversations | Dual-written (Rails: model/reads only) | 73 | insert,raw-write,update | 0 | 37 |
conversation_resolution_assignment_rule_assignee_accounts | conversations | Rails writer | 2 | - | 0 | 2 |
conversation_resolution_assignment_rule_assignee_roles | conversations | Dual-written (Rails: model/reads only) | 3 | raw-write | 0 | 2 |
conversation_resolution_assignment_rule_conditions | conversations | Dual-written (Rails: model/reads only) | 4 | raw-write | 0 | 4 |
conversation_resolution_assignment_rules | conversations | Dual-written (Rails: model/reads only) | 4 | raw-write | 0 | 5 |
conversation_tags | conversations | Dual-written (Rails: model/reads only) | 6 | delete,insert,update | 0 | 6 |
conversation_teams | conversations | Dual-written | 13 | insert,raw-write | 2 | 12 |
conversation_thread_items | conversations | Dual-written (Rails: model/reads only) | 22 | delete,insert,raw-write | 0 | 6 |
conversation_threads | conversations | Dual-written | 15 | delete,insert,raw-write,update | 2 | 9 |
conversations | conversations | Dual-written | 215 | insert,raw-write,update | 9 | 281 |
credits | billing | Dual-written | 7 | raw-write | 1 | 13 |
customer_accounts | customers & complaints | Rails writer | 1 | - | 0 | 12 |
customer_companies | customers & complaints | Dual-written (Rails: model/reads only) | 14 | delete,insert,raw-write,update | 0 | 1 |
customer_complaint_assignee_accounts | customers & complaints | Rails writer | 2 | - | 0 | 1 |
customer_complaint_categories | customers & complaints | Dual-written | 12 | raw-write | 4 | 11 |
customer_complaint_category_keywords | customers & complaints | Dual-written (Rails: model/reads only) | 4 | raw-write | 0 | 3 |
customer_complaints | customers & complaints | Dual-written | 11 | raw-write | 2 | 24 |
customer_fields | customers & complaints | Rails writer | 1 | - | 0 | 8 |
customer_issue_conversation_fields | customers & complaints | Rails writer | 3 | - | 0 | 1 |
customer_issues | customers & complaints | Rails writer | 11 | - | 1 | 21 |
dashboard_accesses | dashboards | Retired (this PR) | 0 | - | 0 | 0 |
dashboard_alerts | dashboards | Retired (this PR) | 0 | - | 0 | 0 |
dashboard_filter_rules | dashboards | Retired (this PR) | 0 | - | 0 | 0 |
dashboard_groups | dashboards | Retired (this PR) | 0 | - | 0 | 0 |
dashboard_preferences | dashboards | Retired (this PR) | 0 | - | 0 | 0 |
dashboard_sections | dashboards | Retired (this PR) | 0 | - | 0 | 0 |
dashboard_widget_type_groups | dashboards | Rails-owned | 0 | - | 0 | 8 |
dashboard_widget_types | dashboards | Rails-owned | 0 | - | 0 | 95 |
dashboard_widgets | dashboards | Retired (this PR) | 1 | - | 0 | 0 |
dashboards | dashboards | Retired (this PR) | 1 | - | 0 | 2 |
data_sources | integrations & sync | Dual-written | 60 | insert,raw-write | 5 | 53 |
digest_emails | notifications & digests | Dual-written | 2 | raw-write | 2 | 26 |
disputes | CRM & clients | Dual-written | 13 | insert,raw-write,update | 2 | 17 |
employee_field_values | other | Dual-written (Rails: model/reads only) | 5 | delete,insert,update | 0 | 2 |
employee_fields | other | Dual-written | 6 | insert,update | 2 | 9 |
employees | workforce | Dual-written | 151 | insert,raw-write,update | 15 | 136 |
evaluation_assignments | QA & evaluations | Dual-written | 8 | delete,insert,update | 2 | 9 |
evaluation_batch_accounts | QA & evaluations | Dual-written (Rails: model/reads only) | 1 | delete,insert | 0 | 1 |
evaluation_batch_assignees | QA & evaluations | Dual-written | 1 | delete,insert,update | 1 | 4 |
evaluation_batch_conversations | QA & evaluations | Dual-written | 5 | delete,insert,raw-write,update | 1 | 11 |
evaluation_batches | QA & evaluations | Dual-written (Rails: model/reads only) | 5 | delete,insert,update | 0 | 16 |
evaluation_contest_criterion_feedbacks | QA & evaluations | Dual-written (Rails: model/reads only) | 7 | insert,update | 0 | 2 |
evaluation_contest_feedbacks | QA & evaluations | Dual-written (Rails: model/reads only) | 7 | insert | 0 | 5 |
evaluation_contest_scorecard_criterion_results | QA & evaluations | Dual-written (Rails: model/reads only) | 4 | insert,update | 0 | 2 |
evaluation_contests | QA & evaluations | Dual-written | 11 | insert,update | 1 | 15 |
evaluation_sampling_rule_counters | QA & evaluations | Dual-written (Rails: model/reads only) | 4 | insert,raw-write,update | 0 | 6 |
evaluation_sampling_rule_targets | QA & evaluations | Rails writer | 3 | - | 0 | 2 |
evaluation_sampling_rules | QA & evaluations | Rails writer | 8 | - | 0 | 15 |
evaluation_scorecard_criterion_result_comments | QA & evaluations | Dual-written (Rails: model/reads only) | 9 | raw-write | 0 | 9 |
flipper_features | framework | Framework | 1 | - | 0 | 0 |
flipper_gates | framework | Framework | 2 | - | 0 | 0 |
group_employees | workforce | Dual-written (Rails: model/reads only) | 11 | delete,insert | 0 | 9 |
group_memberships | workforce | Rails writer | 3 | - | 0 | 2 |
groups | workforce | Dual-written | 20 | insert,raw-write,update | 7 | 74 |
guiding_questions | QA & evaluations | Rails writer | 3 | - | 0 | 1 |
invitation_scopes | identity & access | Rails writer | 2 | - | 0 | 1 |
invitations | identity & access | Dual-written | 8 | raw-write,update | 1 | 10 |
jira_issue_comments | integrations & sync | Dual-written | 4 | insert,update | 1 | 2 |
jira_issue_drafts | integrations & sync | Rails writer | 1 | - | 1 | 5 |
jira_issue_request_field_values | integrations & sync | Dual-written (Rails: model/reads only) | 2 | insert | 0 | 2 |
jira_issues | integrations & sync | Dual-written | 16 | insert,update | 1 | 6 |
jira_request_type_fields | integrations & sync | Dual-written (Rails: model/reads only) | 6 | insert | 0 | 2 |
jira_request_types | integrations & sync | Dual-written (Rails: model/reads only) | 5 | insert | 0 | 9 |
jira_service_desks | integrations & sync | Dual-written | 2 | insert | 2 | 4 |
knowledge_base_crawl_tasks | knowledge base | Dual-written | 2 | insert,update | 1 | 7 |
knowledge_base_document_scorecard_criteria | QA & evaluations | Rails writer | 1 | - | 0 | 1 |
knowledge_base_documents | knowledge base | Dual-written | 25 | insert,raw-write,update | 3 | 33 |
knowledge_base_sections | knowledge base | Dual-written | 4 | insert,update | 4 | 10 |
knowledge_base_sources | knowledge base | Dual-written (Rails: model/reads only) | 10 | insert,update | 0 | 10 |
lines_of_business | workforce | Rails writer | 1 | - | 0 | 4 |
macros | other | Dual-written | 3 | raw-write | 2 | 7 |
membership_scopes | identity & access | Dual-written (Rails: model/reads only) | 9 | raw-write | 0 | 1 |
memberships | identity & access | Dual-written | 59 | raw-write | 9 | 80 |
notification_alert_rules | notifications & digests | Rails writer | 1 | - | 0 | 2 |
organization_data_sources | integrations & sync | Dual-written | 79 | insert,raw-write,update | 5 | 73 |
organization_notification_settings | identity & access | Dual-written (Rails: model/reads only) | 2 | raw-write | 0 | 2 |
organization_risk_level_configurations | identity & access | Dual-written | 8 | raw-write | 1 | 4 |
organization_weekly_digest_configs | notifications & digests | Rails writer | 1 | - | 4 | 8 |
organizations | identity & access | Dual-written | 102 | raw-write,update | 5 | 155 |
partners | workforce | Dual-written | 12 | insert,update | 3 | 23 |
permissions | identity & access | Dual-written | 10 | raw-write | 1 | 15 |
pg_search_documents | framework | Framework | 5 | delete,insert,raw-write,update | 0 | 0 |
pinned_conversations | conversations | Rails writer | 1 | - | 0 | 4 |
qa_agent_evaluation_scorecard_criterion_check_kb_citations | QA & evaluations | Dual-written (Rails: model/reads only) | 3 | raw-write | 0 | 2 |
qa_agent_evaluation_scorecard_criterion_check_results | QA & evaluations | Dual-written (Rails: model/reads only) | 26 | delete,insert,raw-write | 0 | 13 |
qa_agent_evaluation_scorecard_criterion_results | QA & evaluations | Dual-written (Rails: model/reads only) | 52 | delete,insert,raw-write,update | 0 | 30 |
qa_agent_evaluation_scorecard_results | QA & evaluations | Dual-written (Rails: model/reads only) | 51 | delete,insert,raw-write,update | 0 | 18 |
qa_agent_evaluations | QA & evaluations | Dual-written | 91 | insert,raw-write,update | 3 | 75 |
qa_evaluation_requests | QA & evaluations | Dual-written | 19 | raw-write | 2 | 40 |
qa_evaluations | QA & evaluations | Dual-written | 17 | insert,raw-write,update | 1 | 24 |
redaction_rules | other | Dual-written (Rails: model/reads only) | 3 | raw-write | 0 | 2 |
role_permissions | identity & access | Dual-written (Rails: model/reads only) | 9 | raw-write | 0 | 3 |
roles | identity & access | Dual-written | 22 | raw-write | 3 | 31 |
scorecard_cap_rules | QA & evaluations | Rails writer | 5 | - | 0 | 1 |
scorecard_conditions | QA & evaluations | Rails writer | 7 | - | 1 | 7 |
scorecard_criteria | QA & evaluations | Dual-written (Rails: model/reads only) | 50 | raw-write | 0 | 31 |
scorecard_criterion_check_conditions | QA & evaluations | Rails writer | 4 | - | 0 | 2 |
scorecard_criterion_checks | QA & evaluations | Rails writer | 21 | - | 0 | 15 |
scorecard_criterion_score_option_justification_options | QA & evaluations | Rails writer | 25 | - | 0 | 19 |
scorecard_criterion_score_options | QA & evaluations | Rails writer | 35 | - | 0 | 18 |
scorecard_groups | QA & evaluations | Rails writer | 6 | - | 0 | 1 |
scorecards | QA & evaluations | Dual-written | 40 | raw-write | 3 | 71 |
scoring_guides | QA & evaluations | Dual-written | 3 | raw-write | 1 | 9 |
sheet_cells | sheets & tests | Dual-written (Rails: model/reads only) | 5 | insert,update | 0 | 4 |
sheet_changes | sheets & tests | Dual-written (Rails: model/reads only) | 2 | insert | 0 | 4 |
sheet_columns | sheets & tests | Dual-written (Rails: model/reads only) | 7 | insert,update | 0 | 5 |
sheet_rows | sheets & tests | Dual-written (Rails: model/reads only) | 4 | insert,update | 0 | 7 |
sheet_versions | sheets & tests | Dual-written (Rails: model/reads only) | 2 | insert | 0 | 2 |
sheets | sheets & tests | Dual-written (Rails: model/reads only) | 14 | insert,raw-write,update | 0 | 21 |
sla_policies | SLA & schedules | Rails writer | 8 | - | 1 | 5 |
sla_policy_conditions | SLA & schedules | Rails writer | 2 | - | 0 | 2 |
sla_policy_targets | SLA & schedules | Rails writer | 4 | - | 0 | 2 |
slack_channels | integrations & sync | Rails writer | 3 | - | 1 | 5 |
slack_incoming_webhooks | integrations & sync | Rails writer | 3 | - | 0 | 2 |
slack_messages | integrations & sync | Dual-written | 3 | insert | 2 | 3 |
tags | conversations | Dual-written | 6 | delete,insert | 4 | 14 |
team_leads | workforce | Rails writer | 16 | - | 0 | 1 |
teams | workforce | Dual-written | 48 | insert,raw-write,update | 4 | 61 |
test_risk_scenarios | compliance | Rails writer | 0 | - | 0 | 3 |
work_schedules | workforce | Dual-written (Rails: model/reads only) | 7 | raw-write | 0 | 5 |
workspaces | identity & access | Rails writer | 2 | - | 0 | 5 |
zendesk_brands | integrations & sync | Dual-written | 19 | delete,insert,raw-write,update | 3 | 34 |
zendesk_webhook_ticket_syncs | integrations & sync | Dual-written (verified: ZendeskWebhook.record_event! + api2 sync lib) | 2 | delete,insert,update | 0 | 3 |
zendesk_webhooks | integrations & sync | Rails writer | 2 | - | 0 | 16 |