-
Notifications
You must be signed in to change notification settings - Fork 0
Database Schema
All data is stored in a SQLite database (./data/app.db). Entity Framework Core manages the schema and migrations.
Stores each Copilot Studio agent with its complete, independent configuration.
| Column | Type | Purpose |
|---|---|---|
| Id | GUID | Primary key |
| Name | string | Display name |
| Description | string | Free-text description |
| Environment | string |
dev / staging / production
|
| DirectLineBotId | string | Copilot Studio bot identifier |
| DirectLineSecret | string | Web Channel security secret (encrypted) |
| DirectLineUseWebSocket | bool |
true = WebSocket, false = polling |
| DirectLineReplyTimeoutSeconds | int | Per-agent reply timeout |
| DirectLineMaxRetries | int | Retry policy |
| DirectLineBackoffSeconds | int | Backoff interval between retries |
| DirectLineUseWebChannelSecret | bool | Use Web Channel secret vs. token exchange |
| JudgeEndpoint | string | Agent judge LLM URL |
| JudgeApiKey | string | Agent judge API key (encrypted) |
| JudgeModel | string | Judge model deployment name |
| JudgeTemperature | double | Judge temperature |
| JudgeTopP | double | Judge top-p |
| JudgeMaxOutputTokens | int | Judge max output tokens |
| JudgePassThreshold | double | Minimum weighted score to pass (0–1) |
| QuestionGenEndpoint | string? | Per-agent question gen endpoint override (null = global) |
| QuestionGenApiKey | string? | Per-agent question gen API key (null = global, encrypted) |
| QuestionGenModel | string? | Per-agent question gen model override (null = global) |
| QuestionGenSystemPrompt | string? | Per-agent question gen system prompt override (null = global) |
| IsActive | bool | Soft delete |
| CreatedAt | DateTime | Audit |
| UpdatedAt | DateTime | Audit |
| CreatedBy | string | Creator identity |
| Tags | string[] | Categorization tags |
Junction table linking test suites to one or more agents.
| Column | Type | Purpose |
|---|---|---|
| TestSuiteId | GUID | FK → TestSuite |
| AgentId | GUID | FK → Agent |
| Column | Type | Purpose |
|---|---|---|
| Id | GUID | Primary key |
| Name | string | Suite name |
| Description | string | Human-readable description |
| Tags | string[] | Categorization |
| CreatedBy | string | Creator (authenticated user identity) |
| CreatedAt | DateTime | Audit |
| UpdatedAt | DateTime | Audit |
| Version | int | Optimistic concurrency |
| IsActive | bool | Soft delete |
| DefaultTimeoutSeconds | int | Test case timeout |
| MaxRetries | int | Retry policy |
| JudgeSettingId | GUID? | Optional FK → JudgeSettings rubric (null = use agent default) |
| Column | Type | Purpose |
|---|---|---|
| Id | GUID | Primary key |
| SuiteId | GUID | FK → TestSuite |
| Name | string | Test case name |
| UserInput | string[] | Multi-turn user prompts |
| ExpectedIntent | string | Ground truth intent |
| ExpectedEntities | string[] | Expected entity extractions |
| AcceptanceCriteria | string | Pass/fail rubric |
| ReferenceAnswer | string | Optional expected response text |
| Category | string | Test classification |
| Priority | int | Execution order |
| IsGenerated | bool | AI-generated vs manual |
| SourceDocument | GUID | Source document for generated cases |
| Column | Type | Purpose |
|---|---|---|
| Id | GUID | Primary key |
| SuiteId | GUID | FK → TestSuite |
| AgentId | GUID | FK → Agent (which agent was tested) |
| StartedAt | DateTime | Execution start |
| CompletedAt | DateTime? | Execution end (null if running) |
| Status | string |
running / completed / failed
|
| ExecutionUser | string | Who triggered the run |
| GitSha | string | Code version correlation |
| ModelVersion | string | Judge model identifier |
| PromptVersion | string | Prompt template version |
| ConfigSnapshot | JSON | Full config at run time |
| TotalTestCases | int | Count |
| PassedCount | int | Count |
| FailedCount | int | Count |
| SkippedCount | int | Count |
| AverageLatencyMs | double | Mean latency |
| MedianLatencyMs | double | Median latency |
| P95LatencyMs | double | 95th percentile latency |
| Column | Type | Purpose |
|---|---|---|
| Id | GUID | Primary key |
| RunId | GUID | FK → Run |
| TestCaseId | GUID | FK → TestCase |
| Verdict | string |
pass / fail / error / skipped
|
| TaskSuccessScore | double | 0.0–1.0 |
| IntentMatchScore | double | 0.0–1.0 |
| FactualityScore | double | 0.0–1.0 |
| HelpfulnessScore | double | 0.0–1.0 |
| SafetyScore | double | 0.0–1.0 |
| OverallScore | double | Weighted aggregate |
| LatencyMs | long | Response time in ms |
| TurnCount | int | Number of conversation turns |
| TokensUsed | int | Inference tokens consumed |
| JudgeRationale | string | Explanation from AI judge |
| JudgeCitations | string[] | Evidence references |
| ErrorMessage | string | Failure details |
| ExecutedAt | DateTime | When the test ran |
Full conversation transcript per result.
| Column | Type | Purpose |
|---|---|---|
| Id | GUID | Primary key |
| ResultId | GUID | FK → Result |
| Role | string |
user / bot / system
|
| Content | string | Message text |
| Timestamp | DateTime | When sent |
| SequenceNumber | int | Turn order |
| RawActivityJson | JSON | Full Direct Line activity |
| Column | Type | Purpose |
|---|---|---|
| Id | GUID | Primary key |
| Name | string | Original filename |
| DocumentType | string |
pdf / text
|
| ContentHash | string | Deduplication hash |
| UploadedAt | DateTime | Upload timestamp |
| FileSizeBytes | long | File size |
| StoragePath | string | Path on disk |
| Column | Type | Purpose |
|---|---|---|
| Id | GUID | Primary key |
| DocumentId | GUID | FK → Document |
| Text | string | Chunk content |
| TokenCount | int | Estimated tokens |
| ChunkIndex | int | Position in document |
| Category | string | Topic/section tag |
| Embedding | bytes | Optional vector (future) |
Named evaluation rubric presets. Each rubric defines scoring dimension weights, an optional custom judge system prompt, and optional LLM overrides. Assigned to test suites via JudgeSettingId.
| Column | Type | Purpose |
|---|---|---|
| Id | GUID | Primary key |
| Name | string | Rubric name (e.g., "Strict Factuality") |
| PromptTemplate | string | Custom judge system prompt (empty = built-in default) |
| TaskSuccessWeight | double | Weight (0–1) |
| IntentMatchWeight | double | Weight (0–1) |
| FactualityWeight | double | Weight (0–1) |
| HelpfulnessWeight | double | Weight (0–1) |
| SafetyWeight | double | Weight (0–1) |
| PassThreshold | double | Verdict threshold (0–1) |
| UseReferenceAnswer | bool | Include reference answer in judge prompt |
| Temperature | double | LLM temperature (used only when Endpoint is set) |
| TopP | double | LLM top-p (used only when Endpoint is set) |
| MaxOutputTokens | int | LLM max output tokens (used only when Endpoint is set) |
| Endpoint | string? | LLM endpoint override (null = inherit agent judge LLM) |
| ApiKey | string? | LLM API key override (null = inherit agent judge LLM) |
| Model | string? | Model deployment name override (null = inherit agent judge model) |
| IsDefault | bool | Mark as the default rubric |
| CreatedAt | DateTime | Audit |
| UpdatedAt | DateTime | Audit |
Records every mutating operation performed across the application. Written automatically on all Create, Update, Delete, and Run events triggered via the REST API or the Blazor UI. When a request is authenticated with an API key, the key's friendly name is stored as UserId.
| Column | Type | Purpose |
|---|---|---|
| Id | GUID | Primary key |
| Timestamp | DateTime | When the event occurred |
| Action | string |
Create / Update / Delete / Run
|
| EntityType | string | e.g., Agent, TestSuite, TestCase, Document, Run, ApiKey, Result
|
| EntityId | GUID? | ID of the affected entity |
| UserId | string? | Authenticated user identity or API key name (e.g., "CI Pipeline Key") |
| Details | string? | Human-readable description of the operation |
| OldValue | string? | Previous value (for update events, where applicable) |
| NewValue | string? | New value (for update events, where applicable) |
Stores the global default AI question generation configuration. Only one row is used (singleton). Agents may override any of these settings individually.
| Column | Type | Purpose |
|---|---|---|
| Id | GUID | Primary key |
| Endpoint | string | Azure OpenAI endpoint URL |
| ApiKey | string | API key (encrypted) |
| Model | string | Deployment/model name |
| Temperature | double | Sampling temperature |
| TopP | double | Nucleus sampling top-p |
| MaxOutputTokens | int | Max tokens per response |
| SystemPrompt | string? | Custom system prompt override (null = built-in default) |
| UpdatedAt | DateTime | Last updated timestamp |
| UpdatedBy | string | Who last saved it |
Agent ──┐
├── TestSuiteAgents ──── TestSuite ──── TestCase
│ │
│ └── JudgeSettings (optional rubric override)
│
Run ────┤ (FK AgentId + FK SuiteId)
│
└── Result ──── TranscriptMessage
Document ──── Chunk
GlobalQuestionGenerationSetting (singleton; per-agent columns on Agent override it)
JudgeSettings (per-suite rubric presets; agent judge LLM columns are the base)