diff --git a/.gitignore b/.gitignore index da6a097..4f5158a 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,9 @@ testem.log test-results/ .playwright-mcp/ /sql-on-fhir-*.png +/cms125-*.png +/sql-pipeline-*.png +/.claude/ # System files .DS_Store diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index dcc24f9..e24f3fc 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -28,6 +28,7 @@ import { ClipboardManagerComponent } from './components/clipboard-manager/clipbo import { VsacBrowserComponent } from './components/vsac-browser/vsac-browser.component'; import { FhirRegistryImporterComponent } from './components/fhir-registry-importer/fhir-registry-importer.component'; import { SqlOnFhirComponent } from './components/sql-on-fhir/sql-on-fhir.component'; +import { sqlOnFhirGuard } from './components/sql-on-fhir/sql-on-fhir.guard'; export const routes: Routes = [ // Normal app routes @@ -69,7 +70,7 @@ export const routes: Routes = [ { path: 'guidelines', component: GuidelinesComponent }, { path: 'guidelines/:id/testing', component: GuidelinesComponent }, { path: 'guidelines/:id', component: GuidelinesComponent }, - { path: 'sql', component: SqlOnFhirComponent }, + { path: 'sql', component: SqlOnFhirComponent, canActivate: [sqlOnFhirGuard] }, { path: 'about', component: AboutComponent }, { path: 'clipboard', component: ClipboardManagerComponent }, diff --git a/src/app/components/sql-on-fhir/sql-on-fhir.guard.ts b/src/app/components/sql-on-fhir/sql-on-fhir.guard.ts new file mode 100644 index 0000000..0b62ec9 --- /dev/null +++ b/src/app/components/sql-on-fhir/sql-on-fhir.guard.ts @@ -0,0 +1,20 @@ +// Author: Eugene Vestel +// +// Route guard for the experimental SQL-on-FHIR workspace (Issue #23). +// Mirrors the navigation menu gate (experimental + developer flags) so that +// direct navigation to /sql also respects the feature flag rather than only +// hiding the menu entry. Remove this guard when the feature flag is lifted. + +import { inject } from '@angular/core'; +import { CanActivateFn, Router } from '@angular/router'; +import { SettingsService } from '../../services/settings.service'; + +export const sqlOnFhirGuard: CanActivateFn = () => { + const settings = inject(SettingsService).settings(); + const enabled = settings.experimental && settings.developer; + if (enabled) { + return true; + } + // Feature flag off — send the user back to the dashboard. + return inject(Router).createUrlTree(['/']); +}; diff --git a/src/app/services/translation.service.ts b/src/app/services/translation.service.ts index 717420c..e2773ba 100644 --- a/src/app/services/translation.service.ts +++ b/src/app/services/translation.service.ts @@ -15,6 +15,18 @@ import { } from '@cqframework/cql/cql-to-elm'; import { CqlLocatorUtilsService } from './cql-locator-utils.service'; +/** + * `CqlTranslator.toJson()` exists at runtime and in the package's + * `kotlin/cql-to-elm.d.ts`, but the `@cqframework/cql/cql-to-elm` subpath export + * ships only `.mjs` with no paired `types` entry, so the method isn't visible + * to consumers under bundler module resolution. Until that's fixed upstream + * (https://github.com/cqframework/clinical_quality_language/issues/1768) we + * narrow the translator through this minimal interface rather than a bare cast. + */ +interface ElmJsonEmitter { + toJson(): string; +} + export interface TranslationResult { elmXml: string | null; elmJson: string | null; @@ -207,9 +219,8 @@ export class TranslationService { let elmJson: string | null = null; try { - // `toJson` exists at runtime per kotlin/cql-to-elm.d.ts but isn't picked - // up by the @cqframework/cql/cql-to-elm subpath resolution — cast through unknown. - elmJson = (translator as unknown as { toJson: () => string }).toJson(); + // See ElmJsonEmitter above re: upstream type-export gap (#1768). + elmJson = (translator as unknown as ElmJsonEmitter).toJson(); } catch (e) { console.warn('Failed to generate ELM JSON:', e); } @@ -273,9 +284,8 @@ export class TranslationService { let elmJson: string | null = null; try { - // `toJson` exists at runtime per kotlin/cql-to-elm.d.ts but isn't picked - // up by the @cqframework/cql/cql-to-elm subpath resolution — cast through unknown. - elmJson = (translator as unknown as { toJson: () => string }).toJson(); + // See ElmJsonEmitter above re: upstream type-export gap (#1768). + elmJson = (translator as unknown as ElmJsonEmitter).toJson(); } catch (e) { console.warn('Failed to generate ELM JSON:', e); }