Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d0cf4d9
tasks
bradbanister Jun 10, 2026
bf83378
tasks
bradbanister Jun 10, 2026
9de6632
Add change queries OpenAPI base document contract
bradbanister Jun 10, 2026
8b379e5
Add available change versions OpenAPI base path
bradbanister Jun 10, 2026
006d3fd
Add Change Query tracked-change schemas
bradbanister Jun 10, 2026
6a9c566
Remove snapshot OpenAPI artifacts
bradbanister Jun 10, 2026
afe3874
Cover live Change Query filters
bradbanister Jun 10, 2026
ac8bc93
Add Change Query tracked-change OpenAPI paths
bradbanister Jun 10, 2026
496f8cd
Add profile contract coverage for change queries
bradbanister Jun 10, 2026
f416899
Complete change query OpenAPI test coverage task
bradbanister Jun 10, 2026
5014423
Update API schema authoritative artifacts for change queries
bradbanister Jun 10, 2026
daf96fd
Validate Change Query OpenAPI output
bradbanister Jun 10, 2026
b430d0b
build-fix
bradbanister Jun 10, 2026
7249980
Fix tracked-change OpenAPI path schema consistency
bradbanister Jun 10, 2026
68eabbb
Refactor OpenAPI schema property mapping
bradbanister Jun 10, 2026
ac4baa4
Remove implementation progress log
bradbanister Jun 10, 2026
b3c06f3
ok
bradbanister Jun 10, 2026
b86976a
import-fix
bradbanister Jun 10, 2026
bd94539
bug-fix
bradbanister Jun 10, 2026
68eb2bc
ok
bradbanister Jun 10, 2026
8ac4618
new-enhancer
bradbanister Jun 11, 2026
9683d2a
clarification
bradbanister Jun 11, 2026
f5a0201
tests
bradbanister Jun 11, 2026
3e9b27b
sort-requireds
bradbanister Jun 11, 2026
f9cc881
minimum
bradbanister Jun 11, 2026
34b7e72
school-year
bradbanister Jun 11, 2026
c9c9326
test-fixuo
bradbanister Jun 11, 2026
db78918
review-improvements
bradbanister Jun 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/metaed-plugin-edfi-api-schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"@edfi/ed-fi-model-6.1": "3.0.0",
"@types/json-stable-stringify": "^1.2.0",
"ajv": "^8.12.0",
"ajv-formats": "^2.1.1"
"ajv-formats": "^2.1.1",
"openapi-types": "^12.1.3"
},
"scripts": {
"build": "npm run build:clean && npm run build:copy-non-ts && npm run build:dist",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ export function enhance(metaEd: MetaEdEnvironment): EnhancerResult {
const resourceNameMapping: ResourceNameMapping = {};
const caseInsensitiveEndpointNameMapping: CaseInsensitiveEndpointNameMapping = {};
const abstractResources: AbstractResourceMapping = {};
const namespaceEdfiApiSchema: NamespaceEdfiApiSchema = namespace.data.edfiApiSchema as NamespaceEdfiApiSchema;

const projectSchema: ProjectSchema = {
projectName: namespace.projectName as MetaEdProjectName,
Expand All @@ -227,11 +228,13 @@ export function enhance(metaEd: MetaEdEnvironment): EnhancerResult {
isExtensionProject: namespace.isExtension,
educationOrganizationTypes: namespace.data.educationOrganizationTypes as MetaEdResourceName[],
educationOrganizationHierarchy: namespace.data.educationOrganizationHierarchy as EducationOrganizationHierarchy,
domains: (namespace.data.edfiApiSchema as NamespaceEdfiApiSchema).domains,
openApiBaseDocuments: (namespace.data.edfiApiSchema as NamespaceEdfiApiSchema).openApiBaseDocuments,
domains: namespaceEdfiApiSchema.domains,
...(namespace.isExtension || namespaceEdfiApiSchema.openApiBaseDocuments == null
? {}
: { openApiBaseDocuments: namespaceEdfiApiSchema.openApiBaseDocuments }),
};

const { apiSchema } = namespace.data.edfiApiSchema as NamespaceEdfiApiSchema;
const { apiSchema } = namespaceEdfiApiSchema;
apiSchema.projectSchema = projectSchema;

getEntitiesOfTypeForNamespaces([namespace], 'domainEntity').forEach((domainEntity) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { enhance as mergeCoveringFlattenedIdentityPropertyEnhancer } from './Mer
import { enhance as jsonSchemaForInsertEnhancer } from './JsonSchemaForInsertEnhancer';
import { enhance as commonExtensionOverrideCollectorEnhancer } from './CommonExtensionOverrideCollectorEnhancer';
import { enhance as openApiReferenceComponentEnhancer } from './OpenApiReferenceComponentEnhancer';
import { enhance as openApiTrackedChangeKeyFieldEnhancer } from './OpenApiTrackedChangeKeyFieldEnhancer';
import { enhance as openApiRequestBodyComponentEnhancer } from './OpenApiRequestBodyComponentEnhancer';
import { enhance as openApiRequestBodyCollectionComponentEnhancer } from './OpenApiRequestBodyCollectionComponentEnhancer';
import { enhance as openApiRequestBodyCollectionComponentSubclassEnhancer } from './OpenApiRequestBodyCollectionComponentSubclassEnhancer';
Expand Down Expand Up @@ -75,6 +76,7 @@ export function enhancerList(): Enhancer[] {
jsonSchemaForInsertEnhancer,
commonExtensionOverrideCollectorEnhancer,
openApiReferenceComponentEnhancer,
openApiTrackedChangeKeyFieldEnhancer,
openApiRequestBodyComponentEnhancer,
openApiRequestBodyCollectionComponentEnhancer,
openApiRequestBodyCollectionComponentSubclassEnhancer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ export function enhance(metaEd: MetaEdEnvironment): EnhancerResult {
(descriptor.data.edfiApiSchema as EntityApiSchemaData).identityJsonPaths = [];
});

// SchoolYearType is modeled by a hard-coded resource schema with schoolYear as its public identity.
getAllEntitiesOfType(metaEd, 'schoolYearEnumeration').forEach((schoolYearEnumeration) => {
(schoolYearEnumeration.data.edfiApiSchema as EntityApiSchemaData).identityJsonPaths = ['$.schoolYear' as JsonPath];
});

return {
enhancerName: 'IdentityJsonPathsEnhancer',
success: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,81 @@
// See the LICENSE and NOTICES files in the project root for more information.

import { type MetaEdEnvironment, type EnhancerResult, type Namespace } from '@edfi/metaed-core';
import { ComponentsObject, Document } from '../model/OpenApiTypes';
import { ComponentsObject, Document, Operation, PathsObject } from '../model/OpenApiTypes';
import { NamespaceEdfiApiSchema } from '../model/Namespace';
import { createHardcodedParameterResponses, createHardcodedComponentParameters } from './OpenApiSpecificationEnhancerBase';
import { newSchoolYearOpenApis } from './OpenApiComponentEnhancerBase';
import { OpenApiDocumentType, OpenApiDocumentTypeValue } from '../model/api-schema/OpenApiDocumentType';

/**
* Creates the base OpenAPI document structure without paths, schemas, or tags.
* This structure is common to all OpenAPI documents (resources, descriptors, etc.)
* Creates the component object for a document type.
*/
function createBaseOpenApiDocument(metaEd: MetaEdEnvironment, documentType: string): Document {
const components: ComponentsObject = {
function createComponentsObject(documentType: OpenApiDocumentTypeValue): ComponentsObject {
if (documentType === OpenApiDocumentType.CHANGE_QUERIES) {
return {
schemas: {},
responses: {},
parameters: {},
};
}

return {
schemas: {},
responses: createHardcodedParameterResponses(),
parameters: createHardcodedComponentParameters(),
};
}

/**
* Creates the Change Queries available change versions operation.
*/
function createAvailableChangeVersionsOperation(): Operation {
return {
operationId: 'getAvailableChangeVersions',
summary: 'Retrieves the available change version range.',
responses: {
'200': {
description: 'The available change version range was successfully retrieved.',
content: {
'application/json': {
schema: {
type: 'object',
required: ['oldestChangeVersion', 'newestChangeVersion'],
properties: {
oldestChangeVersion: {
type: 'integer',
format: 'int64',
},
newestChangeVersion: {
type: 'integer',
format: 'int64',
},
},
},
},
},
},
},
};
}

/**
* Creates the path object for the standalone Change Queries OpenAPI document.
*/
function createChangeQueriesPaths(): PathsObject {
return {
'/availableChangeVersions': {
get: createAvailableChangeVersionsOperation(),
},
};
}

/**
* Creates the base OpenAPI document structure with document-specific initial paths and components.
* This structure is common to all OpenAPI documents (resources, descriptors, etc.)
*/
function createBaseOpenApiDocument(metaEd: MetaEdEnvironment, documentType: OpenApiDocumentTypeValue): Document {
const components: ComponentsObject = createComponentsObject(documentType);

const openApiDocument: Document = {
openapi: '3.0.0',
Expand All @@ -34,15 +94,18 @@ function createBaseOpenApiDocument(metaEd: MetaEdEnvironment, documentType: stri
url: '',
},
],
paths: {},
paths: documentType === OpenApiDocumentType.CHANGE_QUERIES ? createChangeQueriesPaths() : {},
components,
tags: [],
};

// Add hardcoded SchoolYearTypeReference schema only to resources document
if (documentType === 'resources') {
if (documentType === OpenApiDocumentType.RESOURCES) {
const schoolYearOpenApis = newSchoolYearOpenApis(metaEd.minSchoolYear, metaEd.maxSchoolYear);
components.schemas!.EdFi_SchoolYearTypeReference = schoolYearOpenApis.schoolYearEnumerationOpenApi;
const { schemas } = components;
if (schemas != null) {
schemas.EdFi_SchoolYearTypeReference = schoolYearOpenApis.schoolYearEnumerationOpenApi;
}
}

return openApiDocument;
Expand All @@ -59,10 +122,11 @@ export function enhance(metaEd: MetaEdEnvironment): EnhancerResult {

const namespaceEdfiApiSchema: NamespaceEdfiApiSchema = namespace.data.edfiApiSchema as NamespaceEdfiApiSchema;

// Create base documents for resources and descriptors
// Create base documents for resources, descriptors, and the standalone Change Queries fixed route.
namespaceEdfiApiSchema.openApiBaseDocuments = {
resources: createBaseOpenApiDocument(metaEd, 'resources'),
descriptors: createBaseOpenApiDocument(metaEd, 'descriptors'),
[OpenApiDocumentType.RESOURCES]: createBaseOpenApiDocument(metaEd, OpenApiDocumentType.RESOURCES),
[OpenApiDocumentType.DESCRIPTORS]: createBaseOpenApiDocument(metaEd, OpenApiDocumentType.DESCRIPTORS),
[OpenApiDocumentType.CHANGE_QUERIES]: createBaseOpenApiDocument(metaEd, OpenApiDocumentType.CHANGE_QUERIES),
};
});

Expand Down
Loading
Loading