SaaS 지원 이력을 위한 Cosmos DB 스키마 리뷰
Cosmos DB tenant isolation, partition key, 지원 이력, masking, retention 점검입니다.
SaaS 지원 대시보드에서 가장 위험한 버그는 조용합니다. A 테넌트 검색 결과에 B 테넌트의 청구 메모가 섞입니다. 화면은 열리고 JSON도 정상처럼 보입니다. 이 글은 Claude Code로 Azure Cosmos DB 스키마를 점검합니다.
Key Points
지원 이력은 ticket, message, internal note, audit log를 나눠 봐야 합니다. Cosmos DB에서는 partition key, tenant-aware query, unique key, retention, masking, security를 봅니다.
Workflow For Support History Schema
지원 화면에서 시작합니다. 티켓 목록, 고객 상세, 메시지, 내부 메모, audit log, AI 요약 export를 놓고 Claude Code가 체크리스트를 만듭니다. 계약과 개인정보는 사람이 봅니다.
| Data type | Cosmos DB review | Human review |
|---|---|---|
| Ticket | tenantId, partition key, unique external id | contract and priority |
| Message | body mask, retention, query path | personal data and secrets |
| Internal note | staff-only boundary | refund and incident wording |
| Audit log | retention, actor, action, timestamp | compliance 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 Korean 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
저장하기 쉬운 모양만 보고 schema를 만들면 실패합니다. 유효한 JSON도 테넌트 경계를 지울 수 있습니다.
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. 지원 본문을 그대로 저장해도 되나요?\n\nA. retention과 masking 규칙이 있을 때만 가능합니다. token, secret, email, 계약 정보는 따로 다룹니다.
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
한국어 버전은 SaaS 지원 화면, 테넌트 분리, 지원 이력, masking, 상담 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.
관련 글
SaaS 고객지원 버그 신고를 Claude Code로 재현 절차로 바꾸는 방법
모호한 문의를 재현 단계, 증거, 개발자 전달 메모로 정리하는 지원팀 워크플로입니다.
Claude Code로 B2B SaaS 무료 체험 이메일 5통 설계하기
B2B SaaS 무료 체험 사용자를 첫 성공, 영업 연결, Gumroad 자료, 상담으로 보내는 이메일 흐름입니다.
Claude Code로 SaaS 연동 만들기: API 키, OAuth, Webhook, 감사 로그
Claude Code로 SaaS를 연동하는 실전 가이드. API 키, OAuth, Webhook, 재시도, 시크릿, 감사 로그까지 다룹니다.
무료 PDF: Claude Code 치트시트
이메일을 입력하면 명령, 리뷰 습관, 안전한 워크플로를 정리한 PDF를 받을 수 있습니다.
개인정보를 안전하게 관리하며 스팸을 보내지 않습니다.
작성자 소개
Masa
Claude Code 실무 워크플로와 팀 도입을 검증하는 엔지니어입니다.