Merge pull request #25112 from kappanjoe/domain-spec-type

Add optional `spec.type` to Domain and System entity model
This commit is contained in:
Fredrik Adelöw
2024-08-09 15:52:18 +02:00
committed by GitHub
14 changed files with 86 additions and 2 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/catalog-model': minor
---
Introduce an optional spec.type attribute on the Domain and System entity kinds
@@ -1243,6 +1243,18 @@ system belongs to, e.g. `artists`. This field is optional.
| --------------------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------- |
| [`Domain`](#kind-domain) (default) | Same as this entity, typically `default` | [`partOf`, and reverse `hasPart`](well-known-relations.md#partof-and-haspart) |
### `spec.type` [optional]
The type of system. There is currently no enforced set of values for this field,
so it is left up to the adopting organization to choose a nomenclature that
matches their catalog hierarchy. This field is optional.
Some common values for this field could be:
- `product`
- `service`
- `feature-set`
## Kind: Domain
Describes the following entity kind:
@@ -1303,6 +1315,18 @@ which the domain is a part, e.g. `audio`. This field is optional.
| --------------------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------- |
| [`Domain`](#kind-domain) (default) | Same as this entity, typically `default` | [`partOf`, and reverse `hasPart`](well-known-relations.md#partof-and-haspart) |
### `spec.type` [optional]
The type of domain. There is currently no enforced set of values for this field,
so it is left up to the adopting organization to choose a nomenclature that
matches their catalog hierarchy. This field is optional.
Some common values for this field could be:
- `product-area`
- `product-group`
- `bundle`
## Kind: Location
Describes the following entity kind:
+2
View File
@@ -123,6 +123,7 @@ interface DomainEntityV1alpha1 extends Entity {
spec: {
owner: string;
subdomainOf?: string;
type?: string;
};
}
export { DomainEntityV1alpha1 as DomainEntity };
@@ -454,6 +455,7 @@ interface SystemEntityV1alpha1 extends Entity {
spec: {
owner: string;
domain?: string;
type?: string;
};
}
export { SystemEntityV1alpha1 as SystemEntity };
@@ -13,3 +13,4 @@ metadata:
spec:
owner: team-a
subdomainOf: audio
type: product-group
@@ -6,3 +6,4 @@ metadata:
spec:
owner: user:frank.tiernan
subdomainOf: audio
type: product-group
@@ -8,3 +8,4 @@ metadata:
spec:
owner: team-a
domain: artists
type: service
@@ -6,3 +6,4 @@ metadata:
spec:
owner: team-c
domain: playback
type: feature-set
@@ -6,3 +6,4 @@ metadata:
spec:
owner: team-b
domain: playback
type: feature-set
@@ -32,6 +32,7 @@ describe('DomainV1alpha1Validator', () => {
spec: {
owner: 'me',
subdomainOf: 'parent-domain',
type: 'domain-type',
},
};
});
@@ -84,4 +85,19 @@ describe('DomainV1alpha1Validator', () => {
(entity as any).spec.subdomainOf = '';
await expect(validator.check(entity)).rejects.toThrow(/subdomainOf/);
});
it('accepts missing type', async () => {
delete (entity as any).spec.type;
await expect(validator.check(entity)).resolves.toBe(true);
});
it('rejects wrong type', async () => {
(entity as any).spec.type = 7;
await expect(validator.check(entity)).rejects.toThrow(/type/);
});
it('rejects empty type', async () => {
(entity as any).spec.type = '';
await expect(validator.check(entity)).rejects.toThrow(/type/);
});
});
@@ -33,6 +33,7 @@ export interface DomainEntityV1alpha1 extends Entity {
spec: {
owner: string;
subdomainOf?: string;
type?: string;
};
}
@@ -32,6 +32,7 @@ describe('SystemV1alpha1Validator', () => {
spec: {
owner: 'me',
domain: 'domain',
type: 'system-type',
},
};
});
@@ -84,4 +85,19 @@ describe('SystemV1alpha1Validator', () => {
(entity as any).spec.domain = '';
await expect(validator.check(entity)).rejects.toThrow(/domain/);
});
it('accepts missing type', async () => {
delete (entity as any).spec.type;
await expect(validator.check(entity)).resolves.toBe(true);
});
it('rejects wrong type', async () => {
(entity as any).spec.type = 7;
await expect(validator.check(entity)).rejects.toThrow(/type/);
});
it('rejects empty type', async () => {
(entity as any).spec.type = '';
await expect(validator.check(entity)).rejects.toThrow(/type/);
});
});
@@ -33,6 +33,7 @@ export interface SystemEntityV1alpha1 extends Entity {
spec: {
owner: string;
domain?: string;
type?: string;
};
}
@@ -12,7 +12,8 @@
},
"spec": {
"owner": "artist-relations-team",
"subdomainOf": "audio"
"subdomainOf": "audio",
"type": "product-group"
}
}
],
@@ -45,6 +46,12 @@
"description": "An entity reference to another domain of which the domain is a part.",
"examples": ["audio"],
"minLength": 1
},
"type": {
"type": "string",
"description": "The type of domain. There is currently no enforced set of values for this field, so it is left up to the adopting organization to choose a nomenclature that matches their catalog hierarchy.",
"examples": ["product-group", "bundle"],
"minLength": 1
}
}
}
@@ -12,7 +12,8 @@
},
"spec": {
"owner": "artist-relations-team",
"domain": "artists"
"domain": "artists",
"type": "service"
}
}
],
@@ -45,6 +46,12 @@
"description": "An entity reference to the domain that the system belongs to.",
"examples": ["artists"],
"minLength": 1
},
"type": {
"type": "string",
"description": "The type of system. There is currently no enforced set of values for this field, so it is left up to the adopting organization to choose a nomenclature that matches their catalog hierarchy.",
"examples": ["product", "service", "feature-set"],
"minLength": 1
}
}
}