Apply Composer changes: comprehensive API updates, migrations, middleware, and infrastructure improvements

- Add comprehensive database migrations (001-024) for schema evolution
- Enhance API schema with expanded type definitions and resolvers
- Add new middleware: audit logging, rate limiting, MFA enforcement, security, tenant auth
- Implement new services: AI optimization, billing, blockchain, compliance, marketplace
- Add adapter layer for cloud integrations (Cloudflare, Kubernetes, Proxmox, storage)
- Update Crossplane provider with enhanced VM management capabilities
- Add comprehensive test suite for API endpoints and services
- Update frontend components with improved GraphQL subscriptions and real-time updates
- Enhance security configurations and headers (CSP, CORS, etc.)
- Update documentation and configuration files
- Add new CI/CD workflows and validation scripts
- Implement design system improvements and UI enhancements
This commit is contained in:
defiQUG
2025-12-12 18:01:35 -08:00
parent e01131efaf
commit 9daf1fd378
968 changed files with 160890 additions and 1092 deletions
+55 -44
View File
@@ -1,58 +1,69 @@
import { ApolloClient, InMemoryCache, createHttpLink, from, ApolloLink } from '@apollo/client'
import { setContext } from '@apollo/client/link/context'
import { onError } from '@apollo/client/link/error'
import { handleApiError, getUserFriendlyMessage } from '@/lib/error-handler'
import { ApolloClient, InMemoryCache, split, HttpLink } from '@apollo/client'
import { getMainDefinition } from '@apollo/client/utilities'
import { GraphQLWsLink } from '@apollo/client/link/subscriptions'
import { createClient } from 'graphql-ws'
// HTTP Link - configured to use the GraphQL API
const httpLink = createHttpLink({
uri: process.env.NEXT_PUBLIC_GRAPHQL_ENDPOINT || 'http://localhost:4000/graphql',
const httpLink = new HttpLink({
uri: process.env.NEXT_PUBLIC_GRAPHQL_URL || 'http://localhost:4000/graphql',
})
// Auth Link - for adding authentication headers
const authLink = setContext((_, { headers }) => {
// Get the authentication token from secure storage
let token: string | null = null
if (typeof window !== 'undefined') {
// Try to get from secure storage
token = sessionStorage.getItem('auth_token')
}
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : '',
},
}
})
// Error Link - handle GraphQL and network errors
const errorLink = onError(({ graphQLErrors, networkError, operation, forward }) => {
if (graphQLErrors) {
graphQLErrors.forEach(({ message, locations, path }) => {
const error = handleApiError(new Error(message))
console.error(
`[GraphQL error]: Message: ${getUserFriendlyMessage(error)}, Location: ${locations}, Path: ${path}`
// WebSocket link for subscriptions (only in browser)
const wsLink =
typeof window !== 'undefined'
? new GraphQLWsLink(
createClient({
url: process.env.NEXT_PUBLIC_GRAPHQL_WS_URL || 'ws://localhost:4000/graphql',
connectionParams: () => {
// Add auth token if available
const token = localStorage.getItem('authToken')
return token ? { authorization: `Bearer ${token}` } : {}
},
})
)
})
}
: null
if (networkError) {
const error = handleApiError(networkError)
console.error(`[Network error]: ${getUserFriendlyMessage(error)}`)
}
})
// Split link: use WebSocket for subscriptions, HTTP for queries/mutations
const splitLink =
typeof window !== 'undefined' && wsLink
? split(
({ query }) => {
const definition = getMainDefinition(query)
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
)
},
wsLink,
httpLink
)
: httpLink
// Create Apollo Client
export const apolloClient = new ApolloClient({
link: from([errorLink, authLink, httpLink]),
cache: new InMemoryCache(),
link: splitLink,
cache: new InMemoryCache({
typePolicies: {
NetworkTopology: {
fields: {
nodes: {
merge(existing = [], incoming) {
return incoming
},
},
edges: {
merge(existing = [], incoming) {
return incoming
},
},
},
},
},
}),
defaultOptions: {
watchQuery: {
errorPolicy: 'all',
fetchPolicy: 'cache-and-network',
},
query: {
errorPolicy: 'all',
fetchPolicy: 'cache-first',
},
},
})
+1
View File
@@ -1,4 +1,5 @@
export * from './useAuth'
export * from './useResources'
export * from './useSites'
export * from './useInfrastructure'
+187
View File
@@ -0,0 +1,187 @@
import { useQuery, useMutation } from '@apollo/client'
import {
GET_COUNTRIES,
GET_COUNTRY,
GET_NETWORK_TOPOLOGIES,
GET_NETWORK_TOPOLOGY,
GET_COMPLIANCE_REQUIREMENTS,
GET_COMPLIANCE_REQUIREMENT,
GET_DEPLOYMENT_MILESTONES,
GET_DEPLOYMENT_MILESTONE,
GET_COST_ESTIMATES,
GET_COST_ESTIMATE,
GET_INFRASTRUCTURE_SUMMARY,
UPDATE_NETWORK_TOPOLOGY,
CREATE_DEPLOYMENT_MILESTONE,
UPDATE_DEPLOYMENT_MILESTONE,
DELETE_DEPLOYMENT_MILESTONE,
UPDATE_COMPLIANCE_REQUIREMENT,
UPDATE_COST_ESTIMATE,
} from '../queries/infrastructure'
export function useCountries(filter?: {
region?: string
priority?: string
relationshipType?: string
}) {
return useQuery(GET_COUNTRIES, {
variables: { filter },
fetchPolicy: 'cache-and-network',
})
}
export function useCountry(name: string) {
return useQuery(GET_COUNTRY, {
variables: { name },
skip: !name,
})
}
export function useNetworkTopologies(filter?: { region?: string; entity?: string }) {
return useQuery(GET_NETWORK_TOPOLOGIES, {
variables: { filter },
fetchPolicy: 'cache-and-network',
})
}
export function useNetworkTopology(id: string) {
return useQuery(GET_NETWORK_TOPOLOGY, {
variables: { id },
skip: !id,
})
}
export function useComplianceRequirements(filter?: {
country?: string
region?: string
status?: string
framework?: string
}) {
return useQuery(GET_COMPLIANCE_REQUIREMENTS, {
variables: { filter },
fetchPolicy: 'cache-and-network',
})
}
export function useComplianceRequirement(country: string) {
return useQuery(GET_COMPLIANCE_REQUIREMENT, {
variables: { country },
skip: !country,
})
}
export function useDeploymentMilestones(filter?: {
region?: string
entity?: string
priority?: string
status?: string
}) {
return useQuery(GET_DEPLOYMENT_MILESTONES, {
variables: { filter },
fetchPolicy: 'cache-and-network',
})
}
export function useDeploymentMilestone(id: string) {
return useQuery(GET_DEPLOYMENT_MILESTONE, {
variables: { id },
skip: !id,
})
}
export function useCostEstimates(filter?: {
region?: string
entity?: string
category?: string
}) {
return useQuery(GET_COST_ESTIMATES, {
variables: { filter },
fetchPolicy: 'cache-and-network',
})
}
export function useCostEstimate(region: string, entity: string, category: string) {
return useQuery(GET_COST_ESTIMATE, {
variables: { region, entity, category },
skip: !region || !entity || !category,
})
}
export function useInfrastructureSummary() {
return useQuery(GET_INFRASTRUCTURE_SUMMARY, {
fetchPolicy: 'cache-and-network',
})
}
export function useUpdateNetworkTopology() {
const [mutate, { loading, error }] = useMutation(UPDATE_NETWORK_TOPOLOGY, {
refetchQueries: [{ query: GET_NETWORK_TOPOLOGIES }],
})
return {
updateTopology: mutate,
loading,
error,
}
}
export function useCreateDeploymentMilestone() {
const [mutate, { loading, error }] = useMutation(CREATE_DEPLOYMENT_MILESTONE, {
refetchQueries: [{ query: GET_DEPLOYMENT_MILESTONES }],
})
return {
createMilestone: mutate,
loading,
error,
}
}
export function useUpdateDeploymentMilestone() {
const [mutate, { loading, error }] = useMutation(UPDATE_DEPLOYMENT_MILESTONE, {
refetchQueries: [{ query: GET_DEPLOYMENT_MILESTONES }],
})
return {
updateMilestone: mutate,
loading,
error,
}
}
export function useDeleteDeploymentMilestone() {
const [mutate, { loading, error }] = useMutation(DELETE_DEPLOYMENT_MILESTONE, {
refetchQueries: [{ query: GET_DEPLOYMENT_MILESTONES }],
})
return {
deleteMilestone: mutate,
loading,
error,
}
}
export function useUpdateComplianceRequirement() {
const [mutate, { loading, error }] = useMutation(UPDATE_COMPLIANCE_REQUIREMENT, {
refetchQueries: [{ query: GET_COMPLIANCE_REQUIREMENTS }],
})
return {
updateCompliance: mutate,
loading,
error,
}
}
export function useUpdateCostEstimate() {
const [mutate, { loading, error }] = useMutation(UPDATE_COST_ESTIMATE, {
refetchQueries: [{ query: GET_COST_ESTIMATES }],
})
return {
updateCostEstimate: mutate,
loading,
error,
}
}
@@ -0,0 +1,110 @@
'use client'
import { useSubscription } from '@apollo/client'
import { gql } from 'graphql-tag'
import { useEffect } from 'react'
import { useQueryClient } from '@tanstack/react-query'
const RESOURCE_CREATED_SUBSCRIPTION = gql`
subscription ResourceCreated {
resourceCreated {
id
name
type
status
site {
id
name
}
createdAt
}
}
`
const RESOURCE_UPDATED_SUBSCRIPTION = gql`
subscription ResourceUpdated($id: ID!) {
resourceUpdated(id: $id) {
id
name
type
status
metadata
updatedAt
}
}
`
const RESOURCE_DELETED_SUBSCRIPTION = gql`
subscription ResourceDeleted($id: ID!) {
resourceDeleted(id: $id)
}
`
export function useResourceCreated() {
const queryClient = useQueryClient()
const { data, error } = useSubscription(RESOURCE_CREATED_SUBSCRIPTION)
useEffect(() => {
if (data?.resourceCreated) {
// Invalidate queries to refetch updated data
queryClient.invalidateQueries({ queryKey: ['resources'] })
// Optionally show toast notification
if (typeof window !== 'undefined' && (window as any).toast) {
;(window as any).toast({
title: 'New Resource Created',
description: `${data.resourceCreated.name} has been created`,
})
}
}
}, [data, queryClient])
return { data: data?.resourceCreated, error }
}
export function useResourceUpdated(resourceId: string) {
const queryClient = useQueryClient()
const { data, error } = useSubscription(RESOURCE_UPDATED_SUBSCRIPTION, {
variables: { id: resourceId },
skip: !resourceId,
})
useEffect(() => {
if (data?.resourceUpdated) {
// Invalidate specific resource and list queries
queryClient.invalidateQueries({ queryKey: ['resources'] })
queryClient.invalidateQueries({ queryKey: ['resource', resourceId] })
}
}, [data, queryClient, resourceId])
return { data: data?.resourceUpdated, error }
}
export function useResourceDeleted(resourceId: string) {
const queryClient = useQueryClient()
const { data, error } = useSubscription(RESOURCE_DELETED_SUBSCRIPTION, {
variables: { id: resourceId },
skip: !resourceId,
})
useEffect(() => {
if (data?.resourceDeleted) {
// Remove from cache and invalidate queries
queryClient.removeQueries({ queryKey: ['resource', resourceId] })
queryClient.invalidateQueries({ queryKey: ['resources'] })
if (typeof window !== 'undefined' && (window as any).toast) {
;(window as any).toast({
title: 'Resource Deleted',
description: 'Resource has been deleted',
})
}
}
}, [data, queryClient, resourceId])
return { deletedId: data?.resourceDeleted, error }
}
+87
View File
@@ -0,0 +1,87 @@
import { useSubscription } from '@apollo/client'
import {
RESOURCE_UPDATED,
METRICS_UPDATED,
HEALTH_CHANGED,
FINDING_CREATED,
RISK_CREATED,
} from '../subscriptions'
/**
* Hook for subscribing to resource updates
*/
export function useResourceUpdate(resourceId: string) {
const { data, loading, error } = useSubscription(RESOURCE_UPDATED, {
variables: { resourceId },
skip: !resourceId,
})
return {
resource: data?.resourceUpdated,
loading,
error,
}
}
/**
* Hook for subscribing to metrics updates
*/
export function useMetricsUpdate(resourceId: string, metricType: string) {
const { data, loading, error } = useSubscription(METRICS_UPDATED, {
variables: { resourceId, metricType },
skip: !resourceId || !metricType,
})
return {
metric: data?.metricsUpdated,
loading,
error,
}
}
/**
* Hook for subscribing to health changes
*/
export function useHealthChange(resourceId: string) {
const { data, loading, error } = useSubscription(HEALTH_CHANGED, {
variables: { resourceId },
skip: !resourceId,
})
return {
health: data?.healthChanged,
loading,
error,
}
}
/**
* Hook for subscribing to new findings
*/
export function useFindingCreated(controlId?: string) {
const { data, loading, error } = useSubscription(FINDING_CREATED, {
variables: { controlId: controlId || null },
})
return {
finding: data?.findingCreated,
loading,
error,
}
}
/**
* Hook for subscribing to new risks
*/
export function useRiskCreated(resourceId?: string) {
const { data, loading, error } = useSubscription(RISK_CREATED, {
variables: { resourceId: resourceId || null },
})
return {
risk: data?.riskCreated,
loading,
error,
}
}
+60
View File
@@ -0,0 +1,60 @@
import { gql } from '@apollo/client'
export const GET_API_KEYS = gql`
query GetApiKeys {
apiKeys {
id
name
keyPrefix
permissions
lastUsedAt
expiresAt
createdAt
}
}
`
export const GET_API_KEY = gql`
query GetApiKey($id: ID!) {
apiKey(id: $id) {
id
name
keyPrefix
permissions
lastUsedAt
expiresAt
createdAt
}
}
`
export const CREATE_API_KEY = gql`
mutation CreateApiKey($input: CreateApiKeyInput!) {
createApiKey(input: $input) {
id
name
key
createdAt
}
}
`
export const UPDATE_API_KEY = gql`
mutation UpdateApiKey($id: ID!, $input: UpdateApiKeyInput!) {
updateApiKey(id: $id, input: $input) {
id
name
keyPrefix
permissions
expiresAt
updatedAt
}
}
`
export const REVOKE_API_KEY = gql`
mutation RevokeApiKey($id: ID!) {
revokeApiKey(id: $id)
}
`
+221
View File
@@ -0,0 +1,221 @@
import { gql } from '@apollo/client'
export const GET_SYSTEM_HEALTH = gql`
query GetSystemHealth {
resources(filter: { status: RUNNING }) {
id
name
type
status
site {
id
name
region
}
}
sites {
id
name
status
}
}
`
export const GET_RESOURCE_UTILIZATION = gql`
query GetResourceUtilization($resourceId: ID!, $timeRange: TimeRange!) {
metrics(resourceId: $resourceId, metricType: CPU_USAGE, timeRange: $timeRange) {
values {
timestamp
value
}
}
resource(id: $resourceId) {
id
name
type
}
}
`
export const GET_COST_OVERVIEW = gql`
query GetCostOverview($tenantId: ID!, $timeRange: TimeRange!) {
usage(tenantId: $tenantId, timeRange: $timeRange, granularity: DAY) {
totalCost
currency
byResource {
resourceId
resourceName
cost
}
}
costForecast(tenantId: $tenantId, timeframe: "30D", confidence: 0.95) {
currentCost
predictedCost
confidence
trend
}
}
`
export const GET_BILLING_INFO = gql`
query GetBillingInfo($tenantId: ID!) {
invoices(tenantId: $tenantId, filter: { status: PENDING }) {
id
invoiceNumber
total
status
dueDate
}
budgets(tenantId: $tenantId) {
id
name
amount
currentSpend
remaining
}
}
`
export const GET_API_USAGE = gql`
query GetAPIUsage($timeRange: TimeRange!) {
analyticsAPIUsage(timeRange: $timeRange) {
totalRequests
byEndpoint {
endpoint
requests
errors
}
errorRate
}
}
`
export const GET_DEPLOYMENTS = gql`
query GetDeployments($filter: DeploymentFilter) {
deployments(filter: $filter) {
id
name
status
deploymentType
region
createdAt
completedAt
}
}
`
export const GET_TEST_ENVIRONMENTS = gql`
query GetTestEnvironments {
testEnvironments {
id
name
region
status
resources {
vms
storage
network
}
expiresAt
}
}
`
export const GET_API_KEYS = gql`
query GetAPIKeys {
apiKeys {
id
name
keyPrefix
permissions
lastUsedAt
expiresAt
createdAt
}
}
`
export const GET_DATA_PIPELINE = gql`
query GetDataPipeline {
resources(filter: { type: STORAGE }) {
id
name
status
metadata
}
}
`
export const GET_INTEGRATION_STATUS = gql`
query GetIntegrationStatus {
sites {
id
name
status
region
}
omadaSites {
id
name
accessPoints {
id
status
}
}
}
`
export const GET_COMPLIANCE_STATUS = gql`
query GetComplianceStatus($resourceId: ID) {
policyViolations(filter: { resourceId: $resourceId, status: OPEN }) {
id
severity
message
policyId
createdAt
}
findings(filter: { status: FAIL }) {
id
severity
title
description
resource {
id
name
}
}
}
`
export const GET_SERVICE_ADOPTION = gql`
query GetServiceAdoption {
resources {
id
name
type
createdAt
}
deployments {
id
name
deploymentType
createdAt
}
}
`
export const GET_RESOURCE_USAGE = gql`
query GetResourceUsage($tenantId: ID!, $timeRange: TimeRange!) {
usage(tenantId: $tenantId, timeRange: $timeRange, granularity: HOUR) {
totalCost
byResource {
resourceId
resourceName
resourceType
cost
quantity
}
}
}
`
+332
View File
@@ -0,0 +1,332 @@
import { gql } from '@apollo/client'
export const GET_COUNTRIES = gql`
query GetCountries($filter: CountryFilter) {
countries(filter: $filter) {
name
region
relationshipType
priority
cloudflareCoverage
networkInfrastructurePriority
notes
coordinates {
lat
lng
}
}
}
`
export const GET_COUNTRY = gql`
query GetCountry($name: String!) {
country(name: $name) {
name
region
relationshipType
priority
cloudflareCoverage
networkInfrastructurePriority
notes
coordinates {
lat
lng
}
}
}
`
export const GET_NETWORK_TOPOLOGIES = gql`
query GetNetworkTopologies($filter: TopologyFilter) {
networkTopologies(filter: $filter) {
id
nodes {
id
type
label
region
entity
position {
x
y
}
metadata
}
edges {
id
source
target
type
metadata
}
region
entity
lastUpdated
}
}
`
export const GET_NETWORK_TOPOLOGY = gql`
query GetNetworkTopology($id: ID!) {
networkTopology(id: $id) {
id
nodes {
id
type
label
region
entity
position {
x
y
}
metadata
}
edges {
id
source
target
type
metadata
}
region
entity
lastUpdated
}
}
`
export const GET_COMPLIANCE_REQUIREMENTS = gql`
query GetComplianceRequirements($filter: ComplianceFilter) {
complianceRequirements(filter: $filter) {
country
region
frameworks
status
requirements
lastAuditDate
notes
}
}
`
export const GET_COMPLIANCE_REQUIREMENT = gql`
query GetComplianceRequirement($country: String!) {
complianceRequirement(country: $country) {
country
region
frameworks
status
requirements
lastAuditDate
notes
}
}
`
export const GET_DEPLOYMENT_MILESTONES = gql`
query GetDeploymentMilestones($filter: MilestoneFilter) {
deploymentMilestones(filter: $filter) {
id
title
region
entity
priority
startDate
endDate
status
dependencies
cost
description
}
}
`
export const GET_DEPLOYMENT_MILESTONE = gql`
query GetDeploymentMilestone($id: ID!) {
deploymentMilestone(id: $id) {
id
title
region
entity
priority
startDate
endDate
status
dependencies
cost
description
}
}
`
export const GET_COST_ESTIMATES = gql`
query GetCostEstimates($filter: CostEstimateFilter) {
costEstimates(filter: $filter) {
region
entity
category
monthly
annual
breakdown {
compute
storage
network
licenses
personnel
}
currency
lastUpdated
}
}
`
export const GET_COST_ESTIMATE = gql`
query GetCostEstimate($region: String!, $entity: String!, $category: CostCategory!) {
costEstimate(region: $region, entity: $entity, category: $category) {
region
entity
category
monthly
annual
breakdown {
compute
storage
network
licenses
personnel
}
currency
lastUpdated
}
}
`
export const GET_INFRASTRUCTURE_SUMMARY = gql`
query GetInfrastructureSummary {
infrastructureSummary {
totalCountries
totalRegions
totalCost
deploymentProgress {
planned
inProgress
complete
blocked
}
}
}
`
export const UPDATE_NETWORK_TOPOLOGY = gql`
mutation UpdateNetworkTopology($id: ID!, $input: UpdateTopologyInput!) {
updateNetworkTopology(id: $id, input: $input) {
id
nodes {
id
type
label
region
entity
position {
x
y
}
metadata
}
edges {
id
source
target
type
metadata
}
region
entity
lastUpdated
}
}
`
export const CREATE_DEPLOYMENT_MILESTONE = gql`
mutation CreateDeploymentMilestone($input: CreateMilestoneInput!) {
createDeploymentMilestone(input: $input) {
id
title
region
entity
priority
startDate
endDate
status
dependencies
cost
description
}
}
`
export const UPDATE_DEPLOYMENT_MILESTONE = gql`
mutation UpdateDeploymentMilestone($id: ID!, $input: UpdateMilestoneInput!) {
updateDeploymentMilestone(id: $id, input: $input) {
id
title
region
entity
priority
startDate
endDate
status
dependencies
cost
description
}
}
`
export const DELETE_DEPLOYMENT_MILESTONE = gql`
mutation DeleteDeploymentMilestone($id: ID!) {
deleteDeploymentMilestone(id: $id)
}
`
export const UPDATE_COMPLIANCE_REQUIREMENT = gql`
mutation UpdateComplianceRequirement($country: String!, $input: UpdateComplianceInput!) {
updateComplianceRequirement(country: $country, input: $input) {
country
region
frameworks
status
requirements
lastAuditDate
notes
}
}
`
export const UPDATE_COST_ESTIMATE = gql`
mutation UpdateCostEstimate(
$region: String!
$entity: String!
$category: CostCategory!
$input: UpdateCostEstimateInput!
) {
updateCostEstimate(region: $region, entity: $entity, category: $category, input: $input) {
region
entity
category
monthly
annual
breakdown {
compute
storage
network
licenses
personnel
}
currency
lastUpdated
}
}
`
@@ -0,0 +1,79 @@
import { gql } from '@apollo/client'
export const GET_TEST_ENVIRONMENTS = gql`
query GetTestEnvironments {
testEnvironments {
id
name
region
status
resources {
vms
storage
network
}
expiresAt
createdAt
}
}
`
export const GET_TEST_ENVIRONMENT = gql`
query GetTestEnvironment($id: ID!) {
testEnvironment(id: $id) {
id
name
region
status
resources {
vms
storage
network
}
expiresAt
createdAt
}
}
`
export const CREATE_TEST_ENVIRONMENT = gql`
mutation CreateTestEnvironment($input: CreateTestEnvironmentInput!) {
createTestEnvironment(input: $input) {
id
name
region
status
resources {
vms
storage
network
}
createdAt
}
}
`
export const START_TEST_ENVIRONMENT = gql`
mutation StartTestEnvironment($id: ID!) {
startTestEnvironment(id: $id) {
id
status
}
}
`
export const STOP_TEST_ENVIRONMENT = gql`
mutation StopTestEnvironment($id: ID!) {
stopTestEnvironment(id: $id) {
id
status
}
}
`
export const DELETE_TEST_ENVIRONMENT = gql`
mutation DeleteTestEnvironment($id: ID!) {
deleteTestEnvironment(id: $id)
}
`
+60 -56
View File
@@ -1,75 +1,79 @@
import { gql } from '@apollo/client'
// Subscription for resource updates
export const RESOURCE_UPDATED = gql`
subscription ResourceUpdated($resourceId: ID!) {
resourceUpdated(resourceId: $resourceId) {
export const SUBSCRIBE_TOPOlogy_CHANGES = gql`
subscription SubscribeTopologyChanges($id: ID!) {
topologyChanged(id: $id) {
id
name
type
health
metadata
region
entity
nodes {
id
type
label
position {
x
y
}
}
edges {
id
source
target
type
}
lastUpdated
}
}
`
// Subscription for metrics updates
export const METRICS_UPDATED = gql`
subscription MetricsUpdated($resourceId: ID!, $metricType: MetricType!) {
metricsUpdated(resourceId: $resourceId, metricType: $metricType) {
timestamp
value
labels
}
}
`
// Subscription for health changes
export const HEALTH_CHANGED = gql`
subscription HealthChanged($resourceId: ID!) {
healthChanged(resourceId: $resourceId)
}
`
// Subscription for new findings
export const FINDING_CREATED = gql`
subscription FindingCreated($controlId: ID) {
findingCreated(controlId: $controlId) {
id
control {
id
code
name
}
resource {
id
name
}
export const SUBSCRIBE_COMPLIANCE_CHANGES = gql`
subscription SubscribeComplianceChanges($country: String) {
complianceChanged(country: $country) {
country
region
frameworks
status
severity
title
description
requirements
lastAuditDate
}
}
`
// Subscription for new risks
export const RISK_CREATED = gql`
subscription RiskCreated($resourceId: ID) {
riskCreated(resourceId: $resourceId) {
export const SUBSCRIBE_MILESTONE_CHANGES = gql`
subscription SubscribeMilestoneChanges($region: String) {
milestoneChanged(region: $region) {
id
resource {
id
name
}
pillar {
code
name
}
severity
title
region
entity
priority
startDate
endDate
status
dependencies
cost
description
}
}
`
export const SUBSCRIBE_COST_CHANGES = gql`
subscription SubscribeCostChanges($region: String) {
costChanged(region: $region) {
region
entity
category
monthly
annual
breakdown {
compute
storage
network
licenses
personnel
}
currency
lastUpdated
}
}
`