Advanced (Updated: 7/19/2026)

Cosmos DB Schema Review for SaaS Support History

Review Cosmos DB tenant isolation, partition keys, support history, masking, and retention.

Cosmos DB Schema Review for SaaS Support History

In a SaaS support dashboard, the worst bug is quiet: a search for tenant A returns a billing note from tenant B. The page still loads, the JSON looks valid, and nobody notices until a customer screenshots it. This article reviews Azure Cosmos DB support-history schema with Claude Code before that boundary disappears.

Key Points

Support history needs more than a ticket document. Review ticket, message, internal note, and audit log separately. Cosmos DB partition keys, tenant-aware queries, unique keys, retention, masking, and managed identity choices all affect safety.

Workflow For Support History Schema

Start from the support screen: ticket list, customer detail, message body, staff notes, audit log, and AI summary export. Claude Code reads sample documents and queries, then drafts a checklist. Humans decide contracts, privacy, retention, and customer communication.

Data typeCosmos DB reviewHuman review
TickettenantId, partition key, unique external idcontract and priority
Messagebody mask, retention, query pathpersonal data and secrets
Internal notestaff-only boundaryrefund and incident wording
Audit logretention, actor, action, timestampcompliance and deletion request

What Claude Code Does and What Humans Decide

Claude Code drafts document fields, partition key candidates, query checks, unique key notes, masking rules, and retention notes. Humans decide customer contracts, support text, incident wording, deletion requests, AI usage, and audit retention.

3 Use Cases

Use case 1: Pick a tenant-aware partition key

  • Input: tenant count, ticket count per tenant, list queries, large tenant range.
  • Output: partition key candidates, query examples, hot-tenant risk, container split option.
  • Human review: enterprise contracts, retention, cost, and migration path.

Use case 2: Separate messages and internal notes

  • Input: message document, internal note, attachment fields, AI summary target.
  • Output: customer message fields, staff-only fields, no-log fields, mask list.
  • Human review: personal data, token, incident explanation, refund, legal wording.

Use case 3: Test cross-tenant queries

  • Input: list API, search query, admin screen, test tenants, roles.
  • Output: missing tenantId query, denial cases, expected 403 behavior.
  • Human review: admin search, support impersonation, dedicated enterprise environment.

Copy-Paste Prompt

Act as a English SaaS Azure Cosmos DB schema reviewer.
Goal: prevent cross-tenant support history leaks, weak partition keys, sensitive-text storage, and retention gaps.

Review:
- ticket / message / internal note / audit log documents
- container settings
- partition key candidates
- support list queries
- tenant size ranges
- retention and deletion workflow

Return:
1. tenantId coverage
2. partition key candidates and risks
3. queries missing tenantId
4. support message and internal note boundary
5. unique key candidates
6. sensitive text masking checklist
7. five fields or queries a beginner should inspect today

Working Check Code

// verify-cosmos-saas-schema.mjs
// No dependencies. Run with: node verify-cosmos-saas-schema.mjs
const container = {
  name: "supportHistory",
  partitionKey: "/id",
  uniqueKeys: [],
  ttl: null
};

const documents = [
  {
    id: "ticket-001",
    tenantId: "tenant-a",
    type: "ticket",
    subject: "billing question",
    customerEmail: "[email protected]",
    createdAt: "2026-07-19T09:00:00Z"
  },
  {
    id: "msg-001",
    type: "message",
    ticketId: "ticket-001",
    body: "please check token sk_live_example and invoice",
    createdAt: "2026-07-19T09:02:00Z"
  }
];

const queries = [
  "SELECT * FROM c WHERE c.type = 'ticket' ORDER BY c.createdAt DESC",
  "SELECT * FROM c WHERE c.tenantId = @tenantId AND c.type = 'ticket'"
];

const problems = [];

if (container.partitionKey === "/id") {
  problems.push({ item: "partition key", fix: "use a tenant-aware key such as /tenantId or a tested hierarchical key" });
}
if (!container.uniqueKeys.some((key) => key.paths?.includes("/tenantId") && key.paths?.includes("/externalId"))) {
  problems.push({ item: "unique key", fix: "protect duplicate external ticket ids within a tenant" });
}
if (container.ttl === null) {
  problems.push({ item: "retention", fix: "define retention for support message copies and audit exports" });
}
for (const doc of documents) {
  if (!doc.tenantId) {
    problems.push({ item: "document tenantId", fix: "every support ticket and message needs tenantId" });
  }
  if (/sk_live|token|password|secret/i.test(JSON.stringify(doc))) {
    problems.push({ item: "sensitive text", fix: "mask tokens and secrets before storing support history" });
  }
}
for (const query of queries) {
  if (!/tenantId\s*=\s*@tenantId/.test(query)) {
    problems.push({ item: "query boundary", fix: "include tenantId in customer-facing support queries" });
  }
}

if (problems.length > 0) {
  console.table(problems);
  process.exitCode = 1;
} else {
  console.log("Cosmos DB SaaS schema checklist passed.");
}

Pitfall: Common Failure Cases

SaaS teams fail when they model documents by what is easy to store instead of what is safe to query. A valid JSON document can still erase the tenant boundary.

The first failure is assuming that a tenantId field alone is enough. The query, API authorization, and tests must also carry the tenant boundary.

The second failure is choosing id as the partition key because every document has one. Support screens usually query by tenant and time, so the key should follow real access patterns.

The third failure is sending raw support text into search or AI summaries without masking.

FAQ

Q. Should support text be stored raw?\n\nA. Only with a clear retention and masking rule. Tokens, secrets, emails, and contract details need special handling.

Q. Is tenantId always the right partition key?

A. No. It is a strong candidate for many SaaS screens, but large tenants, query patterns, retention, and cost can change the answer.

Q. Should ticket and message be in one container?

A. Sometimes. Keep review simple by comparing query patterns, retention, permissions, and AI-summary use before deciding.

Q. Where should teams go next?

A. Teams that need Cosmos DB schema, partition key, support history, masking, and authorization review can start from ClaudeCodeLab training.

What I Verified

For the English version, I kept the article tied to SaaS support screens, tenant isolation, support history, masking, and a training CTA. I checked Cosmos DB partitioning, multitenancy, hierarchical partition keys, data modeling, unique keys, and Cosmos DB security. I also checked the CTA, internal link, executable JavaScript, and locale coverage.

#claude-code #saas #cosmos-db #tenant-isolation #support
Free

Free PDF: Claude Code Cheatsheet

Enter your email and download the one-page Claude Code cheatsheet for commands, review habits, and safe workflows.

We handle your data with care and never send spam.

Level up your Claude Code workflow

Start with the free PDF, use Gumroad guides when you need repeatable workflows, and book consultation when rollout or revenue paths need human judgment.

Masa

About the Author

Masa

Engineer focused on practical Claude Code workflows. Runs claudecode-lab.com, a 10-language technical media site.