mirror of
https://github.com/nejimakibird/model-weave.git
synced 2026-07-22 06:51:24 +00:00
feat: improve viewer diagnostics panel
This commit is contained in:
parent
7142d79901
commit
4819e8d5a8
4 changed files with 107 additions and 0 deletions
38
main.js
38
main.js
|
|
@ -12890,6 +12890,7 @@ function validateStandaloneDomains(index, warnings) {
|
|||
});
|
||||
}
|
||||
}
|
||||
validateStandaloneDomainParents(entriesByDomainId, warnings);
|
||||
for (const entries of entriesByDomainId.values()) {
|
||||
if (entries.length < 2) {
|
||||
continue;
|
||||
|
|
@ -12918,6 +12919,24 @@ function validateStandaloneDomains(index, warnings) {
|
|||
compareStandaloneDomainFields(sortedEntries, warnings);
|
||||
}
|
||||
}
|
||||
function validateStandaloneDomainParents(entriesByDomainId, warnings) {
|
||||
for (const entries of entriesByDomainId.values()) {
|
||||
for (const entry of entries) {
|
||||
const parent = entry.domain.parent?.trim();
|
||||
if (!parent || parent === entry.domain.id || entriesByDomainId.has(parent)) {
|
||||
continue;
|
||||
}
|
||||
warnings.push({
|
||||
code: "unresolved-reference",
|
||||
message: formatDomainParentUnknownMessage(parent),
|
||||
severity: "warning",
|
||||
path: entry.path,
|
||||
field: "Domains.parent",
|
||||
context: { rowIndex: entry.domain.rowIndex + 1 }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
function compareStandaloneDomainFields(entries, warnings) {
|
||||
for (const field of STANDALONE_DOMAIN_CANONICAL_FIELDS) {
|
||||
const values = new Set(entries.map((entry) => entry.domain[field]?.trim() ?? ""));
|
||||
|
|
@ -13326,6 +13345,7 @@ function ensureVaultValidation(index) {
|
|||
return;
|
||||
}
|
||||
clearVaultValidationWarnings(index);
|
||||
clearDomainParentNotDefinedWarnings(index);
|
||||
for (const warning of validateVaultIndex(index)) {
|
||||
pushWarning(index.warningsByFilePath, warning.path ?? "vault", {
|
||||
...warning,
|
||||
|
|
@ -13676,6 +13696,24 @@ function clearVaultValidationWarnings(index) {
|
|||
);
|
||||
}
|
||||
}
|
||||
function clearDomainParentNotDefinedWarnings(index) {
|
||||
for (const [path2, warnings] of Object.entries(index.warningsByFilePath)) {
|
||||
const model = index.modelsByFilePath[path2];
|
||||
if (model?.fileType !== "domains") {
|
||||
continue;
|
||||
}
|
||||
index.warningsByFilePath[path2] = warnings.filter(
|
||||
(warning) => !getDomainParentNotDefinedValue(warning)
|
||||
);
|
||||
}
|
||||
}
|
||||
function getDomainParentNotDefinedValue(warning) {
|
||||
if (warning.code !== "unresolved-reference" || warning.field !== "Domains.parent") {
|
||||
return null;
|
||||
}
|
||||
const match = warning.message.match(/^Domain parent "([^"]+)" is not defined\.$/);
|
||||
return match?.[1] ?? null;
|
||||
}
|
||||
function getDuplicateModelKey(model) {
|
||||
if (model.fileType === "markdown") {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
formatDfdObjectUnknownLocalDomainMessage,
|
||||
formatDfdLocalDomainFieldMismatchMessage,
|
||||
formatDfdLocalDomainMissingSharedMessage,
|
||||
formatDomainParentUnknownMessage,
|
||||
formatStandaloneDomainDuplicateMessage,
|
||||
formatStandaloneDomainFieldConflictMessage
|
||||
} from "./domain-diagnostics";
|
||||
|
|
@ -127,6 +128,8 @@ function validateStandaloneDomains(
|
|||
}
|
||||
}
|
||||
|
||||
validateStandaloneDomainParents(entriesByDomainId, warnings);
|
||||
|
||||
for (const entries of entriesByDomainId.values()) {
|
||||
if (entries.length < 2) {
|
||||
continue;
|
||||
|
|
@ -159,6 +162,28 @@ function validateStandaloneDomains(
|
|||
}
|
||||
}
|
||||
|
||||
function validateStandaloneDomainParents(
|
||||
entriesByDomainId: Map<string, Array<{ domain: DomainEntry; path: string }>>,
|
||||
warnings: ValidationWarning[]
|
||||
): void {
|
||||
for (const entries of entriesByDomainId.values()) {
|
||||
for (const entry of entries) {
|
||||
const parent = entry.domain.parent?.trim();
|
||||
if (!parent || parent === entry.domain.id || entriesByDomainId.has(parent)) {
|
||||
continue;
|
||||
}
|
||||
warnings.push({
|
||||
code: "unresolved-reference",
|
||||
message: formatDomainParentUnknownMessage(parent),
|
||||
severity: "warning",
|
||||
path: entry.path,
|
||||
field: "Domains.parent",
|
||||
context: { rowIndex: entry.domain.rowIndex + 1 }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function compareStandaloneDomainFields(
|
||||
entries: Array<{ domain: DomainEntry; path: string }>,
|
||||
warnings: ValidationWarning[]
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@ export function ensureVaultValidation(index: ModelingVaultIndex): void {
|
|||
}
|
||||
|
||||
clearVaultValidationWarnings(index);
|
||||
clearDomainParentNotDefinedWarnings(index);
|
||||
for (const warning of validateVaultIndex(index)) {
|
||||
pushWarning(index.warningsByFilePath, warning.path ?? "vault", {
|
||||
...warning,
|
||||
|
|
@ -599,6 +600,27 @@ function clearVaultValidationWarnings(index: ModelingVaultIndex): void {
|
|||
}
|
||||
}
|
||||
|
||||
function clearDomainParentNotDefinedWarnings(index: ModelingVaultIndex): void {
|
||||
for (const [path, warnings] of Object.entries(index.warningsByFilePath)) {
|
||||
const model = index.modelsByFilePath[path];
|
||||
if (model?.fileType !== "domains") {
|
||||
continue;
|
||||
}
|
||||
|
||||
index.warningsByFilePath[path] = warnings.filter(
|
||||
(warning) => !getDomainParentNotDefinedValue(warning)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getDomainParentNotDefinedValue(warning: ValidationWarning): string | null {
|
||||
if (warning.code !== "unresolved-reference" || warning.field !== "Domains.parent") {
|
||||
return null;
|
||||
}
|
||||
const match = warning.message.match(/^Domain parent "([^"]+)" is not defined\.$/);
|
||||
return match?.[1] ?? null;
|
||||
}
|
||||
|
||||
function getDuplicateModelKey(
|
||||
model: ParsedFileModel
|
||||
): { key: string; id: string } | null {
|
||||
|
|
|
|||
|
|
@ -534,6 +534,24 @@ test("localizes standalone Domain diagnostics", () => {
|
|||
);
|
||||
});
|
||||
|
||||
test("allows standalone Domains parent from another Domains file", () => {
|
||||
const index = buildVaultIndex([
|
||||
domainsFile("COUNTRY_EXAMPLE.md", "COUNTRY_EXAMPLE", "| software_develop | Software develop | business | | Shared parent |"),
|
||||
domainsFile("COUNTRY_EXAMPLE_1.md", "COUNTRY_EXAMPLE_1", [
|
||||
"| software_develop_eigyo_1 | Sales 1 | team | software_develop | External parent |",
|
||||
"| software_develop_kaihatsu_1 | Development 1 | team | software_develop | External parent |"
|
||||
].join("\n"))
|
||||
]);
|
||||
|
||||
const messages = (index.warningsByFilePath["COUNTRY_EXAMPLE_1.md"] ?? []).map(
|
||||
(warning) => warning.message
|
||||
);
|
||||
assert.equal(
|
||||
messages.includes("Domain parent \"software_develop\" is not defined."),
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
test("validates duplicate standalone Domains across files", () => {
|
||||
const index = buildVaultIndex([
|
||||
{
|
||||
|
|
@ -1498,6 +1516,10 @@ id: DOMAIN-DIAGRAM-LOGISTICS
|
|||
["company", "logistics", "warehouse", "team_1"]
|
||||
);
|
||||
assert.equal(resolved.warnings.length, 0);
|
||||
const sourceMessages = (index.warningsByFilePath["model/domains/DOMAINS-WAREHOUSE.md"] ?? []).map(
|
||||
(warning) => warning.message
|
||||
);
|
||||
assert.equal(sourceMessages.includes("Domain parent \"logistics\" is not defined."), false);
|
||||
assert.match(buildDomainMindmapMermaid(resolved.domains), /会社全体(organization)/);
|
||||
assert.match(buildDomainHierarchyMermaid(resolved.domains), /subgraph domain_company/);
|
||||
assert.match(
|
||||
|
|
|
|||
Loading…
Reference in a new issue