Conversation
…mermaid to c# feature
There was a problem hiding this comment.
Pull request overview
This PR adds significant new functionality to DocFlow, expanding it from a code/diagram transformation tool into a comprehensive intelligent documentation and modeling toolkit with three major feature additions:
- AI-powered whiteboard scanning using Claude Vision API to extract Mermaid diagrams from photos
- Scaffolding for API integration automation with OpenAPI parsing, CDM mapping, and SLA validation
- Complete bidirectional C# ↔ Mermaid transformation pipeline with robust parsing and generation
Reviewed changes
Copilot reviewed 45 out of 49 changed files in this pull request and generated 22 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/DocFlow.Diagrams.Tests/Mermaid/MermaidClassDiagramParserTests.cs | Comprehensive test suite for Mermaid parser covering stereotypes, relationships, and round-trip scenarios |
| tests/DocFlow.Diagrams.Tests/Mermaid/MermaidClassDiagramGeneratorTests.cs | Test suite for Mermaid generation with coverage for all entity types and relationship patterns |
| tests/DocFlow.CodeGen.Tests/CSharp/CSharpModelGeneratorTests.cs | Tests for C# code generation including enums, records, interfaces, and DDD patterns |
| tests/DocFlow.CodeAnalysis.Tests/CSharp/CSharpModelParserTests.cs | Tests for C# parsing using Roslyn with entity classification and relationship detection |
| src/DocFlow.Vision/WhiteboardScanner.cs | AI vision implementation for scanning whiteboard photos and extracting Mermaid diagrams |
| src/DocFlow.Integration/Validation/SlaValidator.cs | SLA compliance validator for API data freshness checking |
| src/DocFlow.Integration/Schemas/OpenApi/OpenApiParser.cs | OpenAPI 3.x specification parser for extracting API schemas into semantic model |
| src/DocFlow.Integration/Mapping/CdmMapper.cs | Canonical Data Model mapper with pattern matching and IMS integration |
| src/DocFlow.Integration/Patterns/ApiMappingPatterns.cs | Pre-built mapping patterns for aviation, datetime, identifiers, and audit fields |
| src/DocFlow.Integration/Models/IntegrationSpec.cs | Integration specification models for API-to-CDM mappings |
| src/DocFlow.Diagrams/Mermaid/MermaidClassDiagramParser.cs | Production Mermaid parser with regex-based parsing for class diagrams |
| src/DocFlow.Diagrams/Mermaid/MermaidClassDiagramGenerator.cs | Production Mermaid generator supporting stereotypes and relationships |
| src/DocFlow.CodeGen/CSharp/CSharpModelGenerator.cs | C# code generator with modern C# 12 syntax support |
| src/DocFlow.CodeAnalysis/CSharp/CSharpModelParser.cs | Roslyn-based C# parser extracting semantic model from source code |
| src/DocFlow.CLI/Program.cs | CLI with commands for diagram generation, code generation, round-trip testing, and whiteboard scanning |
| src/DocFlow.AI/Providers/ClaudeProvider.cs | Claude API provider with multi-source API key resolution |
| install.sh / install.ps1 | Installation scripts for Unix and Windows with API key configuration |
| config.json | Configuration file (contains exposed API key - critical security issue) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -0,0 +1,21 @@ | |||
| namespace whiteboard-ddd.Domain; | |||
There was a problem hiding this comment.
The namespace contains a hyphen which is not valid C# syntax. Namespace identifiers cannot contain hyphens. This should be changed to "WhiteboardDdd.Domain" or "Whiteboard_Ddd.Domain".
| namespace whiteboard-ddd.Domain; | |
| namespace WhiteboardDdd.Domain; |
| @@ -0,0 +1,3 @@ | |||
| { | |||
| "anthropicApiKey": "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" | |||
There was a problem hiding this comment.
This file contains a plaintext API key that should not be committed to version control. API keys are sensitive credentials and should be managed through environment variables or secure configuration systems. Remove this file from the repository and add it to .gitignore.
| "anthropicApiKey": "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" | |
| "anthropicApiKey": "YOUR_ANTHROPIC_API_KEY_HERE" |
| class Motorcicle { | ||
| +hasSidecar : boolean | ||
| } | ||
|
|
||
| Vehicle <|-- Car | ||
| Vehicle <|-- Motorcicle No newline at end of file |
There was a problem hiding this comment.
The spelling of "Motorcicle" is incorrect - it should be "Motorcycle".
| class Motorcicle { | |
| +hasSidecar : boolean | |
| } | |
| Vehicle <|-- Car | |
| Vehicle <|-- Motorcicle | |
| class Motorcycle { | |
| +hasSidecar : boolean | |
| } | |
| Vehicle <|-- Car | |
| Vehicle <|-- Motorcycle |
| foreach (var block in response.Content) | ||
| { | ||
| if (block.Type == "text" && !string.IsNullOrEmpty(block.Text)) | ||
| { | ||
| textParts.Add(block.Text); | ||
| } | ||
| } |
There was a problem hiding this comment.
This foreach loop implicitly filters its target sequence - consider filtering the sequence explicitly using '.Where(...)'.
| foreach (var entity in parseResult.Model.Entities.Values) | ||
| { | ||
| if (!combinedModel.Entities.ContainsKey(entity.Id)) | ||
| combinedModel.AddEntity(entity); | ||
| } |
There was a problem hiding this comment.
This foreach loop implicitly filters its target sequence - consider filtering the sequence explicitly using '.Where(...)'.
| .Select(m => new MappingIssue | ||
| { | ||
| Field = m.SourceField, | ||
| Type = m.Confidence == 0 ? MappingIssueType.NoMatch : MappingIssueType.AmbiguousMatch, |
There was a problem hiding this comment.
Equality checks on floating point values can yield unexpected results.
| line.Append($" : {relationship.Name}"); | ||
| } | ||
|
|
||
| sb.AppendLine(line.ToString()); |
There was a problem hiding this comment.
Redundant call to 'ToString' on a String object.
| var compositionsBySource = model.Relationships | ||
| .Where(r => r.Type == RelationshipType.Composition) | ||
| .GroupBy(r => r.SourceEntityId) | ||
| .ToDictionary(g => g.Key, g => g.ToList()); |
There was a problem hiding this comment.
This assignment to compositionsBySource is useless, since its value is never read.
| var associationsBySource = model.Relationships | ||
| .Where(r => r.Type == RelationshipType.Association) | ||
| .GroupBy(r => r.SourceEntityId) | ||
| .ToDictionary(g => g.Key, g => g.ToList()); |
There was a problem hiding this comment.
This assignment to associationsBySource is useless, since its value is never read.
| if (Regex.IsMatch(propName, pattern.Condition, RegexOptions.IgnoreCase)) | ||
| { | ||
| if (pattern.Parameters.TryGetValue("targetField", out var target)) | ||
| { | ||
| return (pattern.Condition, target.ToString()!); | ||
| } | ||
| } |
There was a problem hiding this comment.
These 'if' statements can be combined.
…mermaid to c# feature