diff --git a/.specify/feature.json b/.specify/feature.json new file mode 100644 index 0000000..b97bab1 --- /dev/null +++ b/.specify/feature.json @@ -0,0 +1,3 @@ +{ + "feature_directory": "specs/014-galust-umbrella-chart" +} diff --git a/charts/galust-ai-layer/Chart.lock b/charts/galust-ai-layer/Chart.lock index 40b6f4d..064b230 100644 --- a/charts/galust-ai-layer/Chart.lock +++ b/charts/galust-ai-layer/Chart.lock @@ -14,5 +14,8 @@ dependencies: - name: base repository: https://dasmeta.github.io/helm version: 0.3.30 -digest: sha256:9254d4312b54d6c0960468538a451fb3e6a0f9e5d0a7cc29d121a906263021e1 -generated: "2026-05-15T12:22:19.073404+04:00" +- name: base + repository: https://dasmeta.github.io/helm + version: 0.3.30 +digest: sha256:823220155b5174ccc736955cd0eb71b7599d0a4f5ad6e67eb47fcb41008d0bd0 +generated: "2026-05-28T11:12:11.130707+04:00" diff --git a/charts/galust-ai-layer/Chart.yaml b/charts/galust-ai-layer/Chart.yaml index 80dff5d..be0c9ba 100644 --- a/charts/galust-ai-layer/Chart.yaml +++ b/charts/galust-ai-layer/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: galust-ai-layer description: Galust AI layer umbrella chart for Kubernetes clusters type: application -version: 0.1.5 -appVersion: "0.1.5" +version: 0.1.6 +appVersion: "0.1.6" dependencies: - name: strapi @@ -31,3 +31,8 @@ dependencies: version: 0.3.30 repository: https://dasmeta.github.io/helm condition: orchestrator.enabled + - name: base + alias: frontend + version: 0.3.30 + repository: https://dasmeta.github.io/helm + condition: frontend.enabled diff --git a/charts/galust-ai-layer/README.md b/charts/galust-ai-layer/README.md index 89c825c..839f1f4 100644 --- a/charts/galust-ai-layer/README.md +++ b/charts/galust-ai-layer/README.md @@ -11,6 +11,7 @@ This chart is an umbrella chart for the Galust AI layer services. It wraps the p - MCP use-case service - MCP products service - Orchestrator +- Frontend The chart manages Kubernetes workload configuration for these services. It does not provision cloud infrastructure, databases, DNS records, TLS issuers, IAM roles, ECR policies, or external secrets. @@ -25,6 +26,7 @@ The chart wraps the published `dasmeta/base` chart with one alias per deployable | MCP use-case service | `mcpUseCase.enabled` | `true` | | MCP products service | `mcpProducts.enabled` | `true` | | Orchestrator | `orchestrator.enabled` | `true` | +| Frontend | `frontend.enabled` | `true` | Each component can be disabled independently: @@ -45,7 +47,7 @@ Before deploying, confirm the target cluster has: - AWS access to the target account, usually through an AWS SSO permission set and account assignment managed outside this chart. - Namespace access for `ai-layer`, or permission to create it. - Image pull access for the private ECR images. -- ECR read access for the private repositories used by the backend, MCP, MCP use-case, MCP products and orchestrator images. +- ECR read access for the private repositories used by the backend, MCP, MCP use-case, MCP products, orchestrator and frontend images. - Required application secrets already created in the namespace. - Database connectivity for the backend. - A PVC or storage class suitable for backend uploads. @@ -144,6 +146,8 @@ global: OPENAPI_BASE_URL: &openapiBaseUrl https://api.galust.ai/api OPENAPI_SPEC_URL: &openapiSpecUrl https://api.galust.ai/documentation/openapi.json ORCHESTRATOR_ENDPOINT: &orchestratorEndpoint https://api.galust.ai/orchestrator/api/galust/ask + ORCHESTRATOR_SSE_URL: &orchestratorSseUrl https://api.galust.ai/orchestrator/galust/ask/sse + ORCHESTRATOR_SUPPORT_SSE_URL: &orchestratorSupportSseUrl https://api.galust.ai/orchestrator/galust/support/sse ``` The rest of `values.yaml` reuses these values with YAML anchors, for example: @@ -156,6 +160,12 @@ backend: ingress: hosts: - host: *apiHost + +frontend: + config: + VITE_GALUST_API_BASE_URL: *openapiBaseUrl + VITE_GALUST_ORCHESTRATOR_SSE_URL: *orchestratorSseUrl + VITE_GALUST_ORCHESTRATOR_SUPPORT_SSE_URL: *orchestratorSupportSseUrl ``` Important: YAML anchors are resolved before Helm merges extra values files. If you deploy with `-f examples/galust-ai-layer/values.test.yaml` and only override `global`, Helm will not recalculate aliases already resolved in `values.yaml`. To change domains for another environment, either edit the full values file or provide a values file that also overrides the component `config` and `ingress` fields. @@ -333,6 +343,16 @@ helm upgrade --install galust-ai-layer charts/galust-ai-layer \ --set mcpUseCase.enabled=false ``` +Override the frontend image or disable it for an environment: + +```bash +helm upgrade --install galust-ai-layer charts/galust-ai-layer \ + -n ai-layer \ + --create-namespace \ + --set frontend.image.tag=latest \ + --set frontend.enabled=true +``` + ## Post-Deploy Checks ```bash @@ -350,6 +370,7 @@ Expected default service names: - `ai-layer-mcp-use-case` - `ai-layer-mcp-products` - `ai-layer-orchestrator` +- `ai-layer-frontend` Expected public hosts when ingress is enabled: @@ -362,6 +383,7 @@ Expected public hosts when ingress is enabled: helm dependency update charts/galust-ai-layer helm lint charts/galust-ai-layer helm template galust-ai-layer charts/galust-ai-layer -n ai-layer +helm template galust-ai-layer charts/galust-ai-layer -n ai-layer --set frontend.enabled=false helm template galust-ai-layer charts/galust-ai-layer -n ai-layer --set backend.enabled=false helm template galust-ai-layer charts/galust-ai-layer -n ai-layer -f examples/galust-ai-layer/values.test.yaml ``` diff --git a/charts/galust-ai-layer/templates/NOTES.txt b/charts/galust-ai-layer/templates/NOTES.txt index b38406d..ca7fad8 100644 --- a/charts/galust-ai-layer/templates/NOTES.txt +++ b/charts/galust-ai-layer/templates/NOTES.txt @@ -16,6 +16,9 @@ Enabled components: {{- if .Values.orchestrator.enabled }} - orchestrator: {{ .Values.orchestrator.fullnameOverride | default "orchestrator" }} {{- end }} +{{- if .Values.frontend.enabled }} +- frontend: {{ .Values.frontend.fullnameOverride | default "frontend" }} +{{- end }} Image pull access: - By default the chart references an existing imagePullSecret named {{ include "galust-ai-layer.imagePullSecretName" . }}. diff --git a/charts/galust-ai-layer/values.yaml b/charts/galust-ai-layer/values.yaml index b06f851..244ac2e 100644 --- a/charts/galust-ai-layer/values.yaml +++ b/charts/galust-ai-layer/values.yaml @@ -36,12 +36,15 @@ global: API_URL: &apiUrl https://api.galust.ai API_HOST: &apiHost api.galust.ai APP_URL: &appUrl https://app.galust.ai + APP_HOST: &appHost app.galust.ai MCP_URL: &mcpUrl https://mcp.galust.ai MCP_HOST: &mcpHost mcp.galust.ai ADMIN_URL: &adminUrl https://api.galust.ai/admin OPENAPI_BASE_URL: &openapiBaseUrl https://api.galust.ai/api OPENAPI_SPEC_URL: &openapiSpecUrl https://api.galust.ai/documentation/openapi.json ORCHESTRATOR_ENDPOINT: &orchestratorEndpoint https://api.galust.ai/orchestrator/api/galust/ask + ORCHESTRATOR_SSE_URL: &orchestratorSseUrl https://api.galust.ai/orchestrator/galust/ask/sse + ORCHESTRATOR_SUPPORT_SSE_URL: &orchestratorSupportSseUrl https://api.galust.ai/orchestrator/galust/support/sse gatewayApi: enabled: false @@ -338,3 +341,57 @@ orchestrator: secretName: com-galust-api-tls2 hosts: - *apiHost + +frontend: + enabled: true + gatewayApi: + enabled: false + zeroTrustMesh: + enabled: false + allowTo: [] + fullnameOverride: ai-layer-frontend + version: 0.0.1 + appVersion: 0.0.1 + image: + repository: 565580475168.dkr.ecr.eu-central-1.amazonaws.com/ai-layer-frontend-app + tag: latest + pullPolicy: Always + imagePullSecrets: + - name: ecr-secret + replicaCount: 1 + labels: + version: + name: app-version + value: v0.0.1 + app: + name: app + value: ai-layer-frontend + service: + type: ClusterIP + port: 80 + containerPort: 80 + ingress: + enabled: true + class: nginx + annotations: + kubernetes.io/tls-acme: "true" + cert-manager.io/cluster-issuer: letsencrypt-prod + hosts: + - host: *appHost + paths: + - path: / + pathType: Prefix + backend: + servicePort: 80 + tls: + - clusterIssuer: letsencrypt-prod + secretName: com-galust-app-tls + hosts: + - *appHost + config: + NODE_ENV: production + API_BASE: *apiUrl + API_URL: *openapiBaseUrl + ASK_SSE_URL: *orchestratorSseUrl + SUPPORT_SSE_URL: *orchestratorSupportSseUrl + USE_CASE_RUN_URL_TEMPLATE: https://api.galust.ai/use-cases/{name}/run diff --git a/examples/galust-ai-layer/values.test.yaml b/examples/galust-ai-layer/values.test.yaml index e329e29..791e337 100644 --- a/examples/galust-ai-layer/values.test.yaml +++ b/examples/galust-ai-layer/values.test.yaml @@ -1,4 +1,5 @@ -# Minimal example overlay for externally reachable Galust AI layer URLs and ECR pull-secret refresh. +# helm diff upgrade --install -n ai-layer galust-ai-layer ./charts/galust-ai-layer -f ./examples/galust-ai-layer/values.test.yaml +# Minimal example overlay for externally reachable Galust AI layer URLs, ECR pull-secret refresh, and frontend overrides. imagePullSecret: name: &imagePullSecretName ecr-secret @@ -25,3 +26,7 @@ ecrCredentialsRefresh: orchestrator: envFrom: secret: ai-layer-orchestrator + +frontend: + image: + tag: latest diff --git a/specs/014-galust-umbrella-chart/checklists/requirements.md b/specs/014-galust-umbrella-chart/checklists/requirements.md new file mode 100644 index 0000000..608f06d --- /dev/null +++ b/specs/014-galust-umbrella-chart/checklists/requirements.md @@ -0,0 +1,32 @@ +# Specification Quality Checklist: Galust AI Layer Umbrella Chart + +**Purpose**: Validate specification completeness and quality before proceeding to implementation +**Created**: 2026-05-28 +**Feature**: [spec.md](../spec.md) + +## Content Quality + +- [x] No unresolved implementation ambiguity for the frontend scope +- [x] Focused on operator value and deployment completeness +- [x] Written for chart consumers and maintainers +- [x] All mandatory sections completed + +## Requirement Completeness + +- [x] No [NEEDS CLARIFICATION] markers remain +- [x] Requirements are testable and unambiguous +- [x] Success criteria are measurable +- [x] Acceptance scenarios are defined +- [x] Scope is clearly bounded to `charts/galust-ai-layer` +- [x] Dependencies and assumptions identified + +## Feature Readiness + +- [x] Functional requirements have clear acceptance criteria +- [x] User scenarios cover default render and disable flows +- [x] Feature meets measurable outcomes defined in Success Criteria +- [x] Validation commands are known + +## Notes + +- DMVP-10093 adds frontend to the existing Galust umbrella chart scope. diff --git a/specs/014-galust-umbrella-chart/plan.md b/specs/014-galust-umbrella-chart/plan.md index e82204e..eb152ed 100644 --- a/specs/014-galust-umbrella-chart/plan.md +++ b/specs/014-galust-umbrella-chart/plan.md @@ -5,18 +5,18 @@ ## Summary -Add `charts/galust-ai-layer` as an umbrella chart that deploys the Galust AI layer components to Kubernetes or EKS. Use one `dasmeta/base` dependency alias per component, expose component enable flags, and carry the existing `ai-layer` deployment defaults into chart values. +Add and maintain `charts/galust-ai-layer` as an umbrella chart that deploys the Galust AI layer components to Kubernetes or EKS. Use one `dasmeta/base` dependency alias per service component, expose component enable flags, and carry Galust deployment defaults into chart values. DMVP-10093 extends the chart with the frontend component. ## Technical Context **Language/Version**: Helm 3 chart YAML and Go templates -**Primary Dependencies**: Published `dasmeta/base` chart version `0.3.29`, matching the current shared chart release +**Primary Dependencies**: Published `dasmeta/base` chart version `0.3.30`, matching the current shared chart release **Storage**: Backend uploads PVC, default `ai-layer-strapi-uploads` **Testing**: `helm dependency update`, `helm lint`, `helm template` **Target Platform**: Kubernetes / EKS **Project Type**: Helm chart repository **Constraints**: Do not provision AWS IAM trust, ECR repository policy, or database infrastructure in this chart -**Scale/Scope**: Four long-running Galust workloads +**Scale/Scope**: Six Galust components: backend, mcp, mcp-use-case, mcp-products, orchestrator, and frontend ## Constitution Check @@ -30,6 +30,8 @@ The change is chart-scoped and keeps shared chart logic in `charts/base`. It doe specs/014-galust-umbrella-chart/ ├── spec.md ├── plan.md +├── checklists/ +│ └── requirements.md └── tasks.md ``` @@ -50,5 +52,6 @@ charts/galust-ai-layer/ - Use dependency `condition` fields so component toggles are native Helm behavior. - Set `fullnameOverride` defaults to preserve existing Galust service names. -- Keep ingress defaults disabled to avoid installing Galust production hostnames into clusters by accident. +- Keep ingress defaults aligned with existing component behavior and avoid broadening ingress behavior beyond the requested frontend component. - Provide default image pull secret name `ecr-secret`, with optional chart-rendered docker config secret. +- Add `frontend` as a `dasmeta/base` alias using image `565580475168.dkr.ecr.eu-central-1.amazonaws.com/ai-layer-frontend-app:latest` and port `80`. diff --git a/specs/014-galust-umbrella-chart/spec.md b/specs/014-galust-umbrella-chart/spec.md index ca8743f..bdd0819 100644 --- a/specs/014-galust-umbrella-chart/spec.md +++ b/specs/014-galust-umbrella-chart/spec.md @@ -3,21 +3,21 @@ **Feature Branch**: `014-galust-umbrella-chart` **Created**: 2026-05-11 **Status**: Draft -**Input**: Jira `DMVP-10005` and repo evidence from `ai-layer` +**Input**: Jira `DMVP-10005`, Jira `DMVP-10093`, and repo evidence from `ai-layer` ## User Scenarios & Testing ### User Story 1 - Install All Galust Components (Priority: P1) -Platform operators can install one Helm chart to deploy the Galust backend, MCP, MCP use-case service, and orchestrator into their own EKS cluster. +Platform operators can install one Helm chart to deploy the Galust backend, MCP, MCP use-case service, MCP products service, orchestrator, and frontend into their own EKS cluster. **Why this priority**: This is the core onboarding deliverable. -**Independent Test**: Render the chart with default values and confirm all four component releases are present. +**Independent Test**: Render the chart with default values and confirm all component releases are present. **Acceptance Scenarios**: -1. **Given** default chart values, **When** the chart is rendered, **Then** backend, mcp, mcp-use-case, and orchestrator resources are included. +1. **Given** default chart values, **When** the chart is rendered, **Then** backend, mcp, mcp-use-case, mcp-products, orchestrator, and frontend resources are included. 2. **Given** an existing ECR pull secret name, **When** the chart is installed, **Then** every component references that pull secret. ### User Story 2 - Selectively Disable Components (Priority: P1) @@ -34,6 +34,7 @@ Platform operators can deploy only the components they need for a given environm 2. **Given** `mcp.enabled=false`, **When** the chart is rendered, **Then** mcp resources are omitted. 3. **Given** `mcpUseCase.enabled=false`, **When** the chart is rendered, **Then** mcp-use-case resources are omitted. 4. **Given** `orchestrator.enabled=false`, **When** the chart is rendered, **Then** orchestrator resources are omitted. +5. **Given** `frontend.enabled=false`, **When** the chart is rendered, **Then** frontend resources are omitted. ### User Story 3 - Configure ECR Pull Access (Priority: P2) @@ -47,11 +48,13 @@ Platform operators can point the deployment at a Kubernetes docker registry secr ### Functional Requirements -- **FR-001**: The chart MUST expose independent enable flags for `backend`, `mcp`, `mcpUseCase`, and `orchestrator`. -- **FR-002**: The chart MUST use `dasmeta/base` subchart aliases for the four long-running workloads. +- **FR-001**: The chart MUST expose independent enable flags for `backend`, `mcp`, `mcpUseCase`, `mcpProducts`, `orchestrator`, and `frontend`. +- **FR-002**: The chart MUST use `dasmeta/base` subchart aliases for the long-running service workloads. - **FR-003**: The chart MUST carry defaults derived from the current `ai-layer` deployment files. - **FR-004**: The chart MUST allow image repository, tag, pull policy, and pull secrets to be overridden per component. - **FR-005**: The chart MUST document ECR/IAM provisioning as out of scope. +- **FR-006**: The frontend MUST default to image `565580475168.dkr.ecr.eu-central-1.amazonaws.com/ai-layer-frontend-app:latest`. +- **FR-007**: The frontend MUST expose service and container port `80`. ## Success Criteria @@ -61,3 +64,4 @@ Platform operators can point the deployment at a Kubernetes docker registry secr - **SC-002**: `helm template` succeeds with default values. - **SC-003**: `helm template` succeeds when any one component is disabled. - **SC-004**: The README contains install and pull-secret examples. +- **SC-005**: Rendered default manifests include a frontend workload and Service using port `80`. diff --git a/specs/014-galust-umbrella-chart/tasks.md b/specs/014-galust-umbrella-chart/tasks.md index fbaca8c..ebc3b18 100644 --- a/specs/014-galust-umbrella-chart/tasks.md +++ b/specs/014-galust-umbrella-chart/tasks.md @@ -19,3 +19,17 @@ - [x] T007 Run `helm dependency update charts/galust-ai-layer` - [x] T008 Run `helm lint charts/galust-ai-layer` - [x] T009 Render all components and disabled-component cases with `helm template` + +## Phase 4: DMVP-10093 Support Frontend + +- [x] T010 [US1] Add frontend `base` alias dependency in `charts/galust-ai-layer/Chart.yaml` +- [x] T011 [US1] Add frontend defaults in `charts/galust-ai-layer/values.yaml` +- [x] T012 [US1] Update enabled component output in `charts/galust-ai-layer/templates/NOTES.txt` +- [x] T013 [US1] Update component, prerequisite, service, and validation documentation in `charts/galust-ai-layer/README.md` +- [x] T014 [US1] Update `examples/galust-ai-layer/values.test.yaml` to demonstrate frontend overrides +- [x] T015 Bump `charts/galust-ai-layer/Chart.yaml` version +- [x] T016 Run `helm dependency update charts/galust-ai-layer` +- [x] T017 Run `helm lint charts/galust-ai-layer` +- [x] T018 Run `helm template galust-ai-layer charts/galust-ai-layer -n ai-layer` +- [x] T019 Run `helm template galust-ai-layer charts/galust-ai-layer -n ai-layer --set frontend.enabled=false` +- [x] T020 Run `helm template galust-ai-layer charts/galust-ai-layer -n ai-layer -f examples/galust-ai-layer/values.test.yaml`