feat: add zero-configuration Brainy service template with augmentation-first architecture
- Implement WebSocket augmentation for real-time communication - Implement WebRTC augmentation for peer-to-peer connections - Implement HTTP augmentation as minimal REST fallback - Add auto-discovery augmentation for data pattern analysis - Add adaptive storage augmentation for intelligent resource management - Add environment adapter augmentation for universal compatibility - Template auto-detects environment (browser, Node.js, serverless, containers) - Intelligent transport selection (WebRTC → WebSocket → HTTP) - Automatic storage optimization (memory → filesystem → S3) - Zero configuration required - just npm start - Includes intelligent verb scoring by default - Works in any environment without configuration - Full documentation and examples included
This commit is contained in:
parent
c38c8de10a
commit
768acf66ad
30 changed files with 3548 additions and 0 deletions
135
examples/brainy-service-template/tests/entities.test.js
Normal file
135
examples/brainy-service-template/tests/entities.test.js
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest'
|
||||
import request from 'supertest'
|
||||
import app from '../src/app.js'
|
||||
|
||||
describe('Entity Endpoints', () => {
|
||||
let server
|
||||
let testEntityId
|
||||
|
||||
beforeAll(async () => {
|
||||
server = app.listen(0)
|
||||
// Wait for Brainy to initialize
|
||||
await new Promise(resolve => setTimeout(resolve, 2000))
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
if (server) {
|
||||
server.close()
|
||||
}
|
||||
})
|
||||
|
||||
describe('POST /api/entities', () => {
|
||||
it('should create a new entity', async () => {
|
||||
const entityData = {
|
||||
data: { name: 'Test Entity', type: 'test' },
|
||||
metadata: { category: 'test' }
|
||||
}
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/entities')
|
||||
.send(entityData)
|
||||
.expect(201)
|
||||
.expect('Content-Type', /json/)
|
||||
|
||||
expect(response.body).toHaveProperty('success', true)
|
||||
expect(response.body).toHaveProperty('id')
|
||||
expect(response.body.data).toHaveProperty('data')
|
||||
expect(response.body.data.data).toEqual(entityData.data)
|
||||
|
||||
testEntityId = response.body.id
|
||||
})
|
||||
|
||||
it('should return 400 for missing data', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/entities')
|
||||
.send({})
|
||||
.expect(400)
|
||||
.expect('Content-Type', /json/)
|
||||
|
||||
expect(response.body).toHaveProperty('success', false)
|
||||
expect(response.body.error).toHaveProperty('message')
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /api/entities/:id', () => {
|
||||
it('should retrieve an entity by ID', async () => {
|
||||
if (!testEntityId) {
|
||||
// Create test entity first
|
||||
const entityData = {
|
||||
data: { name: 'Test Entity', type: 'test' }
|
||||
}
|
||||
const createResponse = await request(app)
|
||||
.post('/api/entities')
|
||||
.send(entityData)
|
||||
testEntityId = createResponse.body.id
|
||||
}
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/entities/${testEntityId}`)
|
||||
.expect(200)
|
||||
.expect('Content-Type', /json/)
|
||||
|
||||
expect(response.body).toHaveProperty('success', true)
|
||||
expect(response.body).toHaveProperty('data')
|
||||
expect(response.body.data).toHaveProperty('id', testEntityId)
|
||||
})
|
||||
|
||||
it('should return 404 for non-existent entity', async () => {
|
||||
const response = await request(app)
|
||||
.get('/api/entities/non-existent-id')
|
||||
.expect(404)
|
||||
.expect('Content-Type', /json/)
|
||||
|
||||
expect(response.body).toHaveProperty('success', false)
|
||||
expect(response.body.error).toHaveProperty('statusCode', 404)
|
||||
})
|
||||
})
|
||||
|
||||
describe('POST /api/entities/search', () => {
|
||||
it('should search entities', async () => {
|
||||
const searchQuery = {
|
||||
query: 'test entity',
|
||||
limit: 5,
|
||||
threshold: 0.5
|
||||
}
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/entities/search')
|
||||
.send(searchQuery)
|
||||
.expect(200)
|
||||
.expect('Content-Type', /json/)
|
||||
|
||||
expect(response.body).toHaveProperty('success', true)
|
||||
expect(response.body).toHaveProperty('results')
|
||||
expect(response.body).toHaveProperty('query', searchQuery.query)
|
||||
expect(Array.isArray(response.body.results)).toBe(true)
|
||||
})
|
||||
|
||||
it('should return 400 for missing query', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/entities/search')
|
||||
.send({})
|
||||
.expect(400)
|
||||
.expect('Content-Type', /json/)
|
||||
|
||||
expect(response.body).toHaveProperty('success', false)
|
||||
expect(response.body.error.message).toContain('Query is required')
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /api/entities', () => {
|
||||
it('should list entities with pagination', async () => {
|
||||
const response = await request(app)
|
||||
.get('/api/entities?page=1&limit=10')
|
||||
.expect(200)
|
||||
.expect('Content-Type', /json/)
|
||||
|
||||
expect(response.body).toHaveProperty('success', true)
|
||||
expect(response.body).toHaveProperty('data')
|
||||
expect(response.body).toHaveProperty('pagination')
|
||||
expect(response.body.pagination).toHaveProperty('page', 1)
|
||||
expect(response.body.pagination).toHaveProperty('limit', 10)
|
||||
expect(Array.isArray(response.body.data)).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
75
examples/brainy-service-template/tests/health.test.js
Normal file
75
examples/brainy-service-template/tests/health.test.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { describe, it, expect, beforeAll, afterAll } from 'vitest'
|
||||
import request from 'supertest'
|
||||
import app from '../src/app.js'
|
||||
|
||||
describe('Health Endpoints', () => {
|
||||
let server
|
||||
|
||||
beforeAll(async () => {
|
||||
server = app.listen(0) // Use random available port
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
if (server) {
|
||||
server.close()
|
||||
}
|
||||
})
|
||||
|
||||
describe('GET /health', () => {
|
||||
it('should return health status', async () => {
|
||||
const response = await request(app)
|
||||
.get('/health')
|
||||
.expect('Content-Type', /json/)
|
||||
|
||||
expect(response.status).toBeGreaterThanOrEqual(200)
|
||||
expect(response.body).toHaveProperty('status')
|
||||
expect(response.body).toHaveProperty('timestamp')
|
||||
expect(response.body).toHaveProperty('version')
|
||||
expect(response.body).toHaveProperty('services')
|
||||
expect(response.body.services).toHaveProperty('brainy')
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /health/liveness', () => {
|
||||
it('should return liveness status', async () => {
|
||||
const response = await request(app)
|
||||
.get('/health/liveness')
|
||||
.expect(200)
|
||||
.expect('Content-Type', /json/)
|
||||
|
||||
expect(response.body).toHaveProperty('alive', true)
|
||||
expect(response.body).toHaveProperty('timestamp')
|
||||
expect(response.body).toHaveProperty('pid')
|
||||
expect(response.body).toHaveProperty('uptime')
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /health/readiness', () => {
|
||||
it('should return readiness status', async () => {
|
||||
const response = await request(app)
|
||||
.get('/health/readiness')
|
||||
.expect('Content-Type', /json/)
|
||||
|
||||
expect(response.status).toBeGreaterThanOrEqual(200)
|
||||
expect(response.body).toHaveProperty('ready')
|
||||
expect(response.body).toHaveProperty('timestamp')
|
||||
expect(response.body).toHaveProperty('checks')
|
||||
expect(response.body.checks).toHaveProperty('brainy')
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /health/metrics', () => {
|
||||
it('should return system metrics', async () => {
|
||||
const response = await request(app)
|
||||
.get('/health/metrics')
|
||||
.expect(200)
|
||||
.expect('Content-Type', /json/)
|
||||
|
||||
expect(response.body).toHaveProperty('success', true)
|
||||
expect(response.body).toHaveProperty('data')
|
||||
expect(response.body.data).toHaveProperty('timestamp')
|
||||
expect(response.body.data).toHaveProperty('system')
|
||||
expect(response.body.data.system).toHaveProperty('process')
|
||||
})
|
||||
})
|
||||
})
|
||||
33
examples/brainy-service-template/tests/setup.js
Normal file
33
examples/brainy-service-template/tests/setup.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import { beforeAll, afterAll } from 'vitest'
|
||||
import config from 'config'
|
||||
|
||||
// Global test setup
|
||||
beforeAll(async () => {
|
||||
// Set test environment
|
||||
process.env.NODE_ENV = 'test'
|
||||
process.env.LOG_LEVEL = 'error'
|
||||
|
||||
// Suppress console output during tests
|
||||
const originalConsoleLog = console.log
|
||||
const originalConsoleWarn = console.warn
|
||||
|
||||
console.log = (...args) => {
|
||||
if (!args[0]?.includes?.('Model loaded') && !args[0]?.includes?.('Brainy')) {
|
||||
originalConsoleLog.apply(console, args)
|
||||
}
|
||||
}
|
||||
|
||||
console.warn = (...args) => {
|
||||
if (!args[0]?.includes?.('Model') && !args[0]?.includes?.('TensorFlow')) {
|
||||
originalConsoleWarn.apply(console, args)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
// Cleanup any global resources
|
||||
// Force garbage collection if available
|
||||
if (global.gc) {
|
||||
global.gc()
|
||||
}
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue