feat: initial schemas-app implementation

- Add Nuxt 4 application with Vuetify UI framework
- Implement GraphQL schema registry management interface
- Add Apollo Client integration with Auth0 authentication
- Create organization and API key management
- Add schema and ref browsing capabilities
- Implement organization switcher for multi-org users
- Add delete functionality for organizations and API keys
- Create Kubernetes deployment descriptors
- Add Docker configuration with nginx

Features:
- Dashboard with organization overview
- Schema browsing by ref with supergraph viewing
- Ref management with schema details
- Settings page for organizations and API keys
- User list per organization with provider icons
- Admin-only organization creation
- Delete confirmations with warnings

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-22 16:42:35 +01:00
commit 072e1b10f1
41 changed files with 25557 additions and 0 deletions
+75
View File
@@ -0,0 +1,75 @@
import { ApolloClient, from, HttpLink, InMemoryCache } from '@apollo/client/core'
import { setContext } from '@apollo/client/link/context'
import { DefaultApolloClient } from '@vue/apollo-composable'
export default defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig()
// Determine API URL based on current host
const getApiUrl = () => {
if (typeof window === 'undefined') {
return config.public.apiBase
}
const hostname = window.location.hostname
// If running on localhost, use localhost:8080
if (hostname === 'localhost' || hostname === '127.0.0.1') {
return 'http://localhost:8080'
}
// If running on schemas.unbound.se, use the same domain
if (hostname === 'schemas.unbound.se') {
return 'https://schemas.unbound.se'
}
// Fallback to config or construct from current location
return config.public.apiBase || `${window.location.protocol}//${window.location.host}`
}
// HTTP link for GraphQL endpoint
const httpLink = new HttpLink({
uri: `${getApiUrl()}/query`,
})
// Auth link to add authorization header
const authLink = setContext(async (_, { headers }) => {
try {
// Access Auth0 from the global app instance
const auth0Instance = (nuxtApp.vueApp.config.globalProperties as any).$auth0
if (auth0Instance?.isAuthenticated?.value) {
// Get the access token for API calls
const token = await auth0Instance.getAccessTokenSilently()
if (token) {
return {
headers: {
...headers,
authorization: `Bearer ${token}`,
},
}
}
}
} catch (error) {
console.error('[Apollo] Failed to get Auth0 token:', error)
}
return { headers }
})
// Create Apollo client
const apolloClient = new ApolloClient({
link: from([authLink, httpLink]),
cache: new InMemoryCache(),
})
// Provide Apollo client to the app
nuxtApp.vueApp.provide(DefaultApolloClient, apolloClient)
return {
provide: {
apolloClient,
},
}
})
+17
View File
@@ -0,0 +1,17 @@
import { createAuth0 } from '@auth0/auth0-vue'
export default defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig()
const auth0 = createAuth0({
domain: config.public.auth0.domain,
clientId: config.public.auth0.clientId,
authorizationParams: {
redirect_uri: window.location.origin,
audience: config.public.auth0.audience,
},
cacheLocation: 'localstorage',
})
nuxtApp.vueApp.use(auth0)
})