Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions apps/api/scripts/seed-demo-data-pg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@

import { Pool } from 'pg';
import { randomUUID } from 'crypto';
import { ENV_DEFAULT_ID } from '../src/connections/connection.constants';

const STORAGE_URL =
process.env.STORAGE_URL ||
`postgresql://${process.env.STORAGE_POSTGRES_USER || 'betterdb'}:${process.env.STORAGE_POSTGRES_PASSWORD || 'devpassword'}@${process.env.STORAGE_POSTGRES_HOST || 'localhost'}:${process.env.STORAGE_POSTGRES_PORT || '5432'}/${process.env.STORAGE_POSTGRES_DATABASE || 'betterdb'}`;

// Auto-detected at runtime from the most recently active connection
let CONNECTION_ID = process.env.CONNECTION_ID || 'env-default';
let CONNECTION_ID = process.env.CONNECTION_ID || ENV_DEFAULT_ID;
let SOURCE_HOST = process.env.SOURCE_HOST || 'localhost';
let SOURCE_PORT = parseInt(process.env.SOURCE_PORT || '6379', 10);

Expand Down Expand Up @@ -435,11 +436,12 @@ async function main(): Promise<void> {
console.log('Connected to PostgreSQL');

// Auto-detect the most recently active connection ID and source info
if (CONNECTION_ID === 'env-default') {
if (CONNECTION_ID === ENV_DEFAULT_ID) {
const res = await pool.query(
`SELECT connection_id, source_host, source_port FROM command_log_entries
WHERE connection_id <> 'env-default'
ORDER BY captured_at DESC LIMIT 1`
WHERE connection_id <> $1
ORDER BY captured_at DESC LIMIT 1`,
[ENV_DEFAULT_ID],
);
if (res.rows.length > 0) {
CONNECTION_ID = res.rows[0].connection_id;
Expand Down
9 changes: 5 additions & 4 deletions apps/api/scripts/seed-demo-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Database from 'better-sqlite3';
import * as path from 'path';
import * as fs from 'fs';
import { randomUUID } from 'crypto';
import { ENV_DEFAULT_ID } from '../src/connections/connection.constants';

// Configuration
const DB_PATH = process.env.SQLITE_PATH || path.join(__dirname, '..', 'data', 'betterdb.sqlite');
Expand Down Expand Up @@ -708,7 +709,7 @@ function seedSlowLogEntries(): void {
capturedAt: baseTs + randomInt(0, 5000), // captured shortly after
sourceHost: SOURCE_HOST,
sourcePort: SOURCE_PORT,
connectionId: 'env-default',
connectionId: ENV_DEFAULT_ID,
});
}

Expand Down Expand Up @@ -784,7 +785,7 @@ function seedLatencySnapshots(): void {
eventName,
latestEventTimestamp: eventTs,
maxLatency: baseLatency, // microseconds
connectionId: 'env-default',
connectionId: ENV_DEFAULT_ID,
});
}
}
Expand Down Expand Up @@ -856,7 +857,7 @@ function seedLatencyHistograms(): void {
id: randomUUID(),
timestamp: ts,
data: JSON.stringify(data),
connectionId: 'env-default',
connectionId: ENV_DEFAULT_ID,
});
}

Expand Down Expand Up @@ -952,7 +953,7 @@ function seedMemorySnapshots(): void {
cpuUser,
ioThreadedReads: cumulativeIoReads,
ioThreadedWrites: cumulativeIoWrites,
connectionId: 'env-default',
connectionId: ENV_DEFAULT_ID,
});
}

Expand Down
9 changes: 5 additions & 4 deletions apps/api/src/common/dto/connections.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsString, IsNumber, IsBoolean, IsOptional, Min, Max, MinLength, MaxLength } from 'class-validator';
import { ENV_DEFAULT_ID } from '../../connections/connection.constants';
import type {
ConnectionStatus,
ConnectionCapabilities,
Expand Down Expand Up @@ -31,7 +32,7 @@ export class ConnectionCapabilitiesDto implements ConnectionCapabilities {
* DTO for connection status
*/
export class ConnectionStatusDto implements ConnectionStatus {
@ApiProperty({ description: 'Unique connection identifier', example: 'env-default' })
@ApiProperty({ description: 'Unique connection identifier', example: ENV_DEFAULT_ID })
id: string;

@ApiProperty({ description: 'Human-readable connection name', example: 'Production Redis' })
Expand Down Expand Up @@ -138,15 +139,15 @@ export class ConnectionListResponseDto implements ConnectionListResponse {
@ApiProperty({ description: 'List of all connections', type: [ConnectionStatusDto] })
connections: ConnectionStatus[];

@ApiProperty({ description: 'Current default connection ID', nullable: true, example: 'env-default' })
@ApiProperty({ description: 'Current default connection ID', nullable: true, example: ENV_DEFAULT_ID })
currentId: string | null;
}

/**
* DTO for current connection response
*/
export class CurrentConnectionResponseDto implements CurrentConnectionResponse {
@ApiProperty({ description: 'Current default connection ID', nullable: true, example: 'env-default' })
@ApiProperty({ description: 'Current default connection ID', nullable: true, example: ENV_DEFAULT_ID })
id: string | null;
}

Expand All @@ -170,7 +171,7 @@ export class SuccessResponseDto {
* DTO for individual connection health in all-connections response
*/
export class ConnectionHealthDto {
@ApiProperty({ description: 'Connection ID', example: 'env-default' })
@ApiProperty({ description: 'Connection ID', example: ENV_DEFAULT_ID })
connectionId: string;

@ApiProperty({ description: 'Connection name', example: 'Production Redis' })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
import { ConfigService } from '@nestjs/config';
import { NotFoundException } from '@nestjs/common';
import { ConnectionRegistry } from '../connection-registry.service';
import { ENV_DEFAULT_ID } from '../connection.constants';
import { RuntimeCapabilityTracker } from '../runtime-capability-tracker.service';
import { StoragePort } from '../../common/interfaces/storage-port.interface';
import { DatabasePort } from '../../common/interfaces/database-port.interface';
Expand Down Expand Up @@ -129,14 +130,14 @@ describe('ConnectionRegistry', () => {

expect(mockStorage.saveConnection).toHaveBeenCalledWith(
expect.objectContaining({
id: 'env-default',
id: ENV_DEFAULT_ID,
name: 'Default',
host: 'localhost',
port: 6379,
isDefault: true,
}),
);
expect(registry.getDefaultId()).toBe('env-default');
expect(registry.getDefaultId()).toBe(ENV_DEFAULT_ID);
});

it('should load saved connections on init', async () => {
Expand Down Expand Up @@ -188,7 +189,7 @@ describe('ConnectionRegistry', () => {
});

it('should return specific connection by id', () => {
const conn = registry.get('env-default');
const conn = registry.get(ENV_DEFAULT_ID);
expect(conn).toBeDefined();
});

Expand Down Expand Up @@ -228,9 +229,9 @@ describe('ConnectionRegistry', () => {
});

it('should return config for specific id', () => {
const config = registry.getConfig('env-default');
const config = registry.getConfig(ENV_DEFAULT_ID);
expect(config).toBeDefined();
expect(config?.id).toBe('env-default');
expect(config?.id).toBe(ENV_DEFAULT_ID);
});

it('should return null for non-existent id', () => {
Expand Down Expand Up @@ -289,7 +290,7 @@ describe('ConnectionRegistry', () => {
});

it('should not allow removing env-default connection', async () => {
await expect(registry.removeConnection('env-default')).rejects.toThrow(
await expect(registry.removeConnection(ENV_DEFAULT_ID)).rejects.toThrow(
'Cannot remove the default environment connection',
);
});
Expand Down Expand Up @@ -413,7 +414,7 @@ describe('ConnectionRegistry', () => {

expect(list).toHaveLength(1);
expect(list[0]).toMatchObject({
id: 'env-default',
id: ENV_DEFAULT_ID,
name: 'Default',
host: 'localhost',
port: 6379,
Expand All @@ -438,10 +439,10 @@ describe('ConnectionRegistry', () => {
});

it('should reconnect an existing connection', async () => {
await registry.reconnect('env-default');
await registry.reconnect(ENV_DEFAULT_ID);

// Should have created a new adapter and connected
const conn = registry.get('env-default');
const conn = registry.get(ENV_DEFAULT_ID);
expect(conn.isConnected()).toBe(true);
});

Expand All @@ -459,7 +460,7 @@ describe('ConnectionRegistry', () => {

it('should find connection by host and port', () => {
const id = registry.findIdByHostPort('localhost', 6379);
expect(id).toBe('env-default');
expect(id).toBe(ENV_DEFAULT_ID);
});

it('should return null when not found', () => {
Expand All @@ -470,7 +471,7 @@ describe('ConnectionRegistry', () => {

describe('isEnvDefault', () => {
it('should return true for env-default id', () => {
expect(registry.isEnvDefault('env-default')).toBe(true);
expect(registry.isEnvDefault(ENV_DEFAULT_ID)).toBe(true);
});

it('should return false for other ids', () => {
Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/connections/connection-registry.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { EnvelopeEncryptionService, getEncryptionService } from '../common/utils
import { RuntimeCapabilityTracker } from './runtime-capability-tracker.service';
import { UsageTelemetryService } from '../telemetry/usage-telemetry.service';

// TODO: Export and use across the codebase instead of hardcoded 'env-default' strings
export const ENV_DEFAULT_ID = 'env-default';
export { ENV_DEFAULT_ID } from './connection.constants';
import { ENV_DEFAULT_ID } from './connection.constants';

@Injectable()
export class ConnectionRegistry implements OnModuleInit, OnModuleDestroy {
Expand Down
1 change: 1 addition & 0 deletions apps/api/src/connections/connection.constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const ENV_DEFAULT_ID = 'env-default';
Loading