Add Supabase key validation and simplify frontend state management

- Add backend validation to detect and warn about anon vs service keys
- Prevent startup with incorrect Supabase key configuration
- Consolidate frontend state management following KISS principles
- Remove duplicate state tracking and sessionStorage polling
- Add clear error display when backend fails to start
- Improve .env.example documentation with detailed key selection guide
- Add comprehensive test coverage for validation logic
- Remove unused test results checking to eliminate 404 errors

The implementation now warns users about key misconfiguration while
maintaining backward compatibility. Frontend state is simplified with
MainLayout as the single source of truth for backend status.
This commit is contained in:
Rasmus Widing
2025-08-16 00:10:23 +03:00
parent ad1b8bf70f
commit 3800280f2e
19 changed files with 848 additions and 317 deletions

View File

@@ -1,6 +1,7 @@
import { render, screen, fireEvent } from '@testing-library/react'
import { describe, test, expect, vi } from 'vitest'
import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest'
import React from 'react'
import { credentialsService } from '../src/services/credentialsService'
describe('Error Handling Tests', () => {
test('api error simulation', () => {
@@ -196,4 +197,40 @@ describe('Error Handling Tests', () => {
fireEvent.click(screen.getByText('500 Error'))
expect(screen.getByRole('alert')).toHaveTextContent('Something went wrong on our end')
})
})
describe('CredentialsService Error Handling', () => {
const originalFetch = global.fetch
beforeEach(() => {
global.fetch = vi.fn() as any
})
afterEach(() => {
global.fetch = originalFetch
})
test('should handle network errors with context', async () => {
const mockError = new Error('Network request failed')
;(global.fetch as any).mockRejectedValueOnce(mockError)
await expect(credentialsService.createCredential({
key: 'TEST_KEY',
value: 'test',
is_encrypted: false,
category: 'test'
})).rejects.toThrow(/Network error while creating credential 'test_key'/)
})
test('should preserve context in error messages', async () => {
const mockError = new Error('database error')
;(global.fetch as any).mockRejectedValueOnce(mockError)
await expect(credentialsService.updateCredential({
key: 'OPENAI_API_KEY',
value: 'sk-test',
is_encrypted: true,
category: 'api_keys'
})).rejects.toThrow(/Updating credential 'OPENAI_API_KEY' failed/)
})
})

View File

@@ -74,7 +74,7 @@ describe('Onboarding Detection Tests', () => {
{ key: 'LLM_PROVIDER', value: 'openai', category: 'rag_strategy' }
]
const apiKeyCreds: NormalizedCredential[] = [
{ key: 'OPENAI_API_KEY', is_encrypted: true, category: 'api_keys' }
{ key: 'OPENAI_API_KEY', is_encrypted: true, encrypted_value: 'encrypted_sk-test123', category: 'api_keys' }
]
expect(isLmConfigured(ragCreds, apiKeyCreds)).toBe(true)

View File

@@ -2,6 +2,9 @@ import { expect, afterEach, vi } from 'vitest'
import { cleanup } from '@testing-library/react'
import '@testing-library/jest-dom/vitest'
// Set required environment variables for tests
process.env.ARCHON_SERVER_PORT = '8181'
// Clean up after each test
afterEach(() => {
cleanup()
@@ -15,7 +18,7 @@ global.fetch = vi.fn(() =>
text: () => Promise.resolve(''),
status: 200,
} as Response)
)
) as any
// Mock WebSocket
class MockWebSocket {