VoiceNotes is an Arduino sketch for the Waveshare ESP32-C6-LCD-0.85 that records meetings and voice memos to microSD and turns them into notes: - Records 16 kHz mono WAV (up to 4 h) from the ES7210 dual mics, with a boosted preamp and soft-limited digital gain - Transcribes via an OpenAI-compatible speech-to-text API in ~10 min parts cut at quiet points, with retries and resume after failures - Summarizes the transcript with Claude into meeting notes (decisions, action items, topics with timestamps), streamed to and from the card - Copies the notes to Nextcloud over WebDAV - Shows recording/processing state on the 0.85" LCD and the LED ring - Works around the board's SD card failing multi-sector reads Credentials live in VoiceNotes/secrets.h, which is git-ignored; see secrets.example.h. Also adds the Microsoft CDM customer service SQL implementation (DDL, sample data, reporting queries and docs). Its README is renamed to CDM_README.md so the repository README stays at the top level. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
17 KiB
Microsoft Common Data Model - Customer Service Implementation Guide
Overview
This document provides a comprehensive guide to the SQL Server implementation of the Microsoft Common Data Model (CDM) for Customer Service applications. The implementation includes 26 core tables, 4 analytical views, and sample data for testing and development.
Architecture Overview
The CDM Customer Service model is organized into seven functional categories:
1. Foundation Entities (4 tables)
The core tables that represent the fundamental business entities:
- User: System users with access to the CRM
- Site: Business locations/branches
- Account: Customer organizations
- Contact: Individual persons associated with accounts
2. Service Configuration (5 tables)
Tables for managing services and resources:
- Service: Services offered to customers
- Resource: Users or equipment that can be scheduled
- FacilityEquipment: Physical resources that can be scheduled
- SchedulingGroup: Resource groups or teams
- ResourceSpecification: Selection rules for resource allocation
3. Contract Management (3 tables)
Tables for managing customer contracts:
- Contract: Customer service contracts with terms and conditions
- ContractLine: Line items within contracts specifying services
- ServiceContractContact: Contacts associated with contracts
4. Entitlement Management (3 tables)
Tables for managing customer entitlements:
- Entitlement: Support entitlements for customers
- EntitlementContact: Contacts entitled to use services
- EntitlementProduct: Services/products covered by entitlements
5. Case Management (3 tables)
Tables for tracking service requests and issues:
- Case: Primary table for service request cases
- CaseResolution: Resolution details for cases
- ChildIncidentCount: Tracking of child incidents
6. Service Activities (2 tables)
Tables for scheduling and tracking service work:
- ServiceActivity: Scheduled service activities and appointments
- ActivityParty: Persons or groups associated with activities
7. Complementary Features (6 tables)
Additional tables supporting the core functionality:
- KnowledgeArticle: Knowledge base articles
- KnowledgeArticleIncident: Association between articles and cases
- IncidentKnowledgeBaseRecord: Knowledge base records for cases
- SLAKPIInstance: Service level agreement KPI tracking
- Task: Generic task activities
- ResourceExpansion: Resource expansion configurations
Table Descriptions and Key Fields
Foundation Tables
User
Represents users with access to the CRM system.
| Field | Type | Description |
|---|---|---|
| userId | UNIQUEIDENTIFIER | Primary key |
| userName | NVARCHAR(200) | Unique username |
| firstName | NVARCHAR(100) | First name |
| lastName | NVARCHAR(100) | Last name |
| NVARCHAR(200) | Email address | |
| phone | NVARCHAR(20) | Phone number |
| mobilePhone | NVARCHAR(20) | Mobile phone |
| isActive | BIT | Active status |
| createdOn | DATETIME2(7) | Creation timestamp |
| createdBy | UNIQUEIDENTIFIER | Creator user ID |
| modifiedOn | DATETIME2(7) | Last modification timestamp |
| modifiedBy | UNIQUEIDENTIFIER | Last modifier user ID |
Account
Represents customer organizations.
| Field | Type | Description |
|---|---|---|
| accountId | UNIQUEIDENTIFIER | Primary key |
| accountName | NVARCHAR(200) | Account name |
| accountNumber | NVARCHAR(50) | Unique account number |
| accountType | NVARCHAR(50) | Type: Prospect, Customer, Partner |
| parentAccountId | UNIQUEIDENTIFIER | Parent account (hierarchical) |
| ownerUserId | UNIQUEIDENTIFIER | Account owner |
| siteId | UNIQUEIDENTIFIER | Primary site |
| industry | NVARCHAR(100) | Industry classification |
| numberOfEmployees | INT | Employee count |
| revenue | DECIMAL(18,2) | Annual revenue |
| isActive | BIT | Active status |
Contact
Represents individual persons.
| Field | Type | Description |
|---|---|---|
| contactId | UNIQUEIDENTIFIER | Primary key |
| firstName | NVARCHAR(100) | First name |
| lastName | NVARCHAR(100) | Last name |
| NVARCHAR(200) | Email address | |
| accountId | UNIQUEIDENTIFIER | Associated account |
| jobTitle | NVARCHAR(100) | Job title |
| department | NVARCHAR(100) | Department |
Site
Represents business locations.
| Field | Type | Description |
|---|---|---|
| siteId | UNIQUEIDENTIFIER | Primary key |
| siteName | NVARCHAR(200) | Location name |
| city | NVARCHAR(100) | City |
| stateProvince | NVARCHAR(100) | State/Province |
| country | NVARCHAR(100) | Country |
| isHeadquarters | BIT | Headquarters flag |
Case Management Tables
Case
The primary table for service request tracking.
| Field | Type | Description |
|---|---|---|
| caseId | UNIQUEIDENTIFIER | Primary key |
| caseNumber | NVARCHAR(50) | Unique case number |
| title | NVARCHAR(200) | Case subject |
| description | NVARCHAR(MAX) | Detailed description |
| priority | NVARCHAR(50) | Low, Medium, High, Critical |
| severity | NVARCHAR(50) | Low, Medium, High |
| status | NVARCHAR(50) | Active, Resolved, Closed, Waiting |
| accountId | UNIQUEIDENTIFIER | Associated account |
| contactId | UNIQUEIDENTIFIER | Associated contact |
| ownerUserId | UNIQUEIDENTIFIER | Assigned to user |
| contractId | UNIQUEIDENTIFIER | Associated contract |
| entitlementId | UNIQUEIDENTIFIER | Associated entitlement |
| parentCaseId | UNIQUEIDENTIFIER | Parent case (hierarchical) |
| createdDate | DATETIME2(7) | Creation date |
| resolvedDate | DATETIME2(7) | Resolution date |
| closedDate | DATETIME2(7) | Close date |
| resolutionNotes | NVARCHAR(MAX) | Resolution details |
| billingStatus | NVARCHAR(50) | Billable, Non-billable |
CaseResolution
Details about how a case was resolved.
| Field | Type | Description |
|---|---|---|
| resolutionId | UNIQUEIDENTIFIER | Primary key |
| caseId | UNIQUEIDENTIFIER | Associated case |
| description | NVARCHAR(MAX) | Resolution description |
| resolutionType | NVARCHAR(100) | Type of resolution |
| actualServiceDuration | INT | Time spent (minutes) |
| totalCostAmount | DECIMAL(18,2) | Cost of resolution |
ServiceActivity
Scheduled service work for cases.
| Field | Type | Description |
|---|---|---|
| activityId | UNIQUEIDENTIFIER | Primary key |
| subject | NVARCHAR(200) | Activity subject |
| serviceId | UNIQUEIDENTIFIER | Service type |
| caseId | UNIQUEIDENTIFIER | Associated case |
| ownerUserId | UNIQUEIDENTIFIER | Assigned technician |
| startTime | DATETIME2(7) | Start timestamp |
| endTime | DATETIME2(7) | End timestamp |
| duration | INT | Duration in minutes |
| location | NVARCHAR(200) | Service location |
| status | NVARCHAR(50) | Scheduled, In Progress, Completed, Cancelled |
Contract Tables
Contract
Customer service contracts.
| Field | Type | Description |
|---|---|---|
| contractId | UNIQUEIDENTIFIER | Primary key |
| contractNumber | NVARCHAR(100) | Unique contract number |
| contractName | NVARCHAR(200) | Contract name |
| accountId | UNIQUEIDENTIFIER | Customer account |
| startDate | DATE | Contract start date |
| endDate | DATE | Contract end date |
| status | NVARCHAR(50) | Draft, Active, Expired, Cancelled |
| contractValue | DECIMAL(18,2) | Total contract value |
| contractType | NVARCHAR(50) | Service, Support, Maintenance |
ContractLine
Line items within contracts.
| Field | Type | Description |
|---|---|---|
| contractLineId | UNIQUEIDENTIFIER | Primary key |
| contractId | UNIQUEIDENTIFIER | Parent contract |
| lineNumber | INT | Line sequence |
| serviceId | UNIQUEIDENTIFIER | Service included |
| quantityIncluded | INT | Units/hours included |
| quantityUsed | INT | Units/hours used |
| price | DECIMAL(18,2) | Line price |
| discount | DECIMAL(18,2) | Discount amount |
Entitlement Tables
Entitlement
Customer support entitlements.
| Field | Type | Description |
|---|---|---|
| entitlementId | UNIQUEIDENTIFIER | Primary key |
| entitlementName | NVARCHAR(200) | Entitlement name |
| accountId | UNIQUEIDENTIFIER | Customer account |
| startDate | DATE | Start date |
| endDate | DATE | Expiration date |
| type | NVARCHAR(50) | Support, Service, Training |
| unitType | NVARCHAR(50) | Cases, Hours, Incidents |
| unitCount | INT | Number of units |
| status | NVARCHAR(50) | Active, Inactive, Expired |
Relationships and Hierarchy
Key Relationships
-
Account Hierarchy
- Accounts can have parent accounts (self-referencing)
- Useful for parent-subsidiary relationships
-
Case Hierarchy
- Cases can have parent cases (self-referencing)
- Useful for tracking related or child incidents
-
Resource Allocation
- Resources can be users, equipment, or facilities
- Resources are organized into SchedulingGroups
- ResourceSpecifications define which resources are needed
-
Contract Structure
- Contracts contain ContractLines
- Each ContractLine specifies a Service and quantity
- ServiceContractContact links contacts to contracts
-
Entitlement Management
- Entitlements provide support/service access
- EntitlementContact associates specific contacts
- EntitlementProduct specifies which services are covered
-
Case Tracking
- Cases are linked to Accounts and Contacts
- ServiceActivities are scheduled for Cases
- CaseResolution provides final resolution details
- SLAKPIInstance tracks SLA compliance
Indexes for Performance
The implementation includes 36 indexes optimized for common queries:
Search Indexes
- Email-based lookups (User, Contact)
- Account number searches
- Case number searches
Filtering Indexes
- Status fields (Case, Contract, Service, etc.)
- Priority and severity filtering
- Type classification (AccountType, ResourceType)
Relationship Indexes
- Foreign key relationships
- Parent-child relationships
- User ownership
Time-Range Indexes
- Date range queries for contracts and activities
- Appointment/schedule lookups
Views for Analytics
Four pre-built views support common analytical queries:
1. v_ActiveCasesSummary
Shows all active and waiting cases with:
- Case number and title
- Priority and owner
- Associated account and contact
- Days since creation
SELECT * FROM cdm.v_ActiveCasesSummary
WHERE priority = 'High'
ORDER BY daysSinceCreation DESC;
2. v_ContractSummary
Shows contract overview with:
- Contract details and status
- Associated account
- Number of line items
- Contract value and owner
SELECT * FROM cdm.v_ContractSummary
WHERE status = 'Active'
ORDER BY contractValue DESC;
3. v_CaseServiceActivity
Shows service activities linked to cases:
- Case and activity details
- Assigned technician
- Time information
SELECT * FROM cdm.v_CaseServiceActivity
WHERE status = 'Scheduled'
ORDER BY startTime;
4. v_CustomerSupportStatus
Summarizes support metrics by customer:
- Total, active, resolved, closed cases
- Active entitlements per customer
SELECT * FROM cdm.v_CustomerSupportStatus
ORDER BY activeCases DESC;
Sample Data Included
The implementation includes realistic sample data:
Organizations
- 4 sample accounts (Acme Corporation, TechVision Inc, Global Services Ltd, StartupX)
- 3 sample sites (New York, Los Angeles, Chicago)
People
- 5 system users (support staff and managers)
- 5 customer contacts with different roles
Services & Resources
- 5 service types (Technical Support, Installation, Maintenance, Training, Premium Support)
- 5 resources (3 user resources, 2 facility/equipment resources)
Contracts & Entitlements
- 3 active contracts with 4 contract lines
- 3 entitlements with varying support levels
Cases & Activities
- 4 sample cases with various priorities and statuses
- 3 service activities scheduled for cases
Knowledge & Tracking
- 4 knowledge articles (some published, some draft)
- 4 SLA KPI instances tracking case performance
Key Design Decisions
-
GUID as Primary Keys: Ensures global uniqueness and distributed system compatibility
-
Audit Columns: All tables include
createdBy,createdOn,modifiedBy,modifiedOnfor tracking -
Soft Deletes:
isActivebit field instead of hard deletes for data preservation -
Extensibility: Schema designed to accommodate CDM extensions
-
Performance: Indexes on common query patterns (status, owner, dates, hierarchies)
-
Type Safety: Enumerated values (as strings) for status, priority, and type fields
-
Relationships: Cascading deletes on child records for data integrity
Common Queries
Find Active Cases by Priority
SELECT
c.caseNumber,
c.title,
a.accountName,
u.firstName + ' ' + u.lastName AS owner,
DATEDIFF(DAY, c.createdDate, GETUTCDATE()) AS dayOpen
FROM cdm.Case c
JOIN cdm.Account a ON c.accountId = a.accountId
JOIN cdm.[User] u ON c.ownerUserId = u.userId
WHERE c.status = 'Active'
AND c.priority = 'High'
ORDER BY c.createdDate;
Contract Utilization Report
SELECT
c.contractNumber,
c.contractName,
cl.lineNumber,
s.serviceName,
cl.quantityIncluded,
cl.quantityUsed,
CAST(CAST(cl.quantityUsed AS FLOAT) / CAST(cl.quantityIncluded AS FLOAT) * 100 AS DECIMAL(5,2)) AS utilizationPercent
FROM cdm.Contract c
JOIN cdm.ContractLine cl ON c.contractId = cl.contractId
JOIN cdm.Service s ON cl.serviceId = s.serviceId
WHERE c.status = 'Active'
ORDER BY c.contractNumber, cl.lineNumber;
Customer Support Effectiveness
SELECT
a.accountName,
COUNT(DISTINCT c.caseId) AS totalCases,
AVG(DATEDIFF(HOUR, c.createdDate, ISNULL(c.resolvedDate, GETUTCDATE()))) AS avgResolutionHours,
SUM(CASE WHEN c.status = 'Closed' THEN 1 ELSE 0 END) AS closedCases,
SUM(CASE WHEN c.status = 'Closed' THEN 1 ELSE 0 END) * 100 / COUNT(*) AS closureRate
FROM cdm.Account a
LEFT JOIN cdm.Case c ON a.accountId = c.accountId
WHERE c.createdDate >= DATEADD(MONTH, -3, GETUTCDATE())
GROUP BY a.accountId, a.accountName
ORDER BY closureRate DESC;
SLA Compliance Dashboard
SELECT
c.caseNumber,
c.title,
sk.kpiName,
sk.metricValue,
sk.metricUnit,
sk.targetValue,
sk.status,
CASE
WHEN sk.isCritical = 1 THEN 'CRITICAL'
WHEN sk.isWarning = 1 THEN 'WARNING'
ELSE 'OK'
END AS severity
FROM cdm.Case c
JOIN cdm.SLAKPIInstance sk ON c.caseId = sk.caseId
WHERE c.status IN ('Active', 'Waiting')
ORDER BY c.priority DESC, sk.status;
Performance Recommendations
Query Optimization
- Always filter by
statuswhen querying cases - Use date range filters for time-based queries
- Include
isActivefilters to exclude deleted records
Maintenance Tasks
- Index Maintenance: Rebuild fragmented indexes monthly
- Statistics: Update statistics weekly on high-traffic tables
- Archive Old Cases: Archive cases older than 2 years
- Partition Large Tables: Consider partitioning Case table by year
Monitoring
- Monitor slow queries on Case, ServiceActivity tables
- Check index fragmentation regularly
- Monitor deadlocks in concurrent environments
Extending the Model
Adding Custom Fields
- Create extension tables with CDM entity foreign keys
- Use naming convention:
CustomField_<YourCompany>_<EntityName> - Maintain referential integrity
Adding Custom Entities
- Follow the same design patterns as existing entities
- Include audit columns (createdBy, createdOn, etc.)
- Add isActive soft delete column
- Create appropriate indexes
Adding Business Logic
- Create stored procedures for complex operations
- Use triggers for audit trails
- Implement views for reporting
Security Considerations
- Row-Level Security: Implement using views or stored procedures
- User Permissions: Restrict based on ownerUserId and siteId
- Audit Trail: All modifications tracked in audit columns
- Data Encryption: Consider encryption for sensitive fields
- Access Control: Use database roles for different user types
Migration from Other Systems
When migrating from other CRM systems:
- Data Mapping: Create mapping between legacy and CDM fields
- Entity Matching: Match legacy entities to CDM entities
- History Preservation: Use createdBy/createdOn for original data dates
- Validation: Implement data quality checks during migration
- Testing: Validate all relationships and referential integrity
Support and Resources
- Microsoft CDM Documentation: https://github.com/microsoft/CDM
- SQL Server Best Practices: Microsoft SQL Server documentation
- Performance Tuning: SQL Server Query Store analysis
Version History
- v1.0 (2026-09-23): Initial implementation with 26 core tables, 4 views, and sample data
License
This implementation is provided as a reference based on the Microsoft Common Data Model specification.