2025-01-05 12:13:46 +01:00
|
|
|
export interface Configuration {
|
|
|
|
|
server: ServerConfiguration;
|
2025-01-05 20:25:48 +01:00
|
|
|
account: AccountConfiguration;
|
2025-01-12 18:25:04 +01:00
|
|
|
user: UserConfiguration;
|
2025-01-05 12:13:46 +01:00
|
|
|
postgres: PostgresConfiguration;
|
|
|
|
|
redis: RedisConfiguration;
|
|
|
|
|
avatarS3: S3Configuration;
|
|
|
|
|
fileS3: S3Configuration;
|
2025-01-05 12:36:40 +01:00
|
|
|
smtp: SmtpConfiguration;
|
2025-01-05 12:13:46 +01:00
|
|
|
ai: AiConfiguration;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ServerConfiguration {
|
|
|
|
|
name: string;
|
|
|
|
|
avatar: string;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-05 20:25:48 +01:00
|
|
|
export type AccountVerificationType = 'automatic' | 'manual' | 'email';
|
|
|
|
|
export interface AccountConfiguration {
|
|
|
|
|
verificationType: AccountVerificationType;
|
|
|
|
|
otpTimeout: number;
|
|
|
|
|
allowGoogleLogin: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-12 18:25:04 +01:00
|
|
|
export interface UserConfiguration {
|
|
|
|
|
storageLimit: bigint;
|
|
|
|
|
maxFileSize: bigint;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-05 12:13:46 +01:00
|
|
|
export interface PostgresConfiguration {
|
|
|
|
|
url: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface RedisConfiguration {
|
|
|
|
|
url: string;
|
|
|
|
|
db: number;
|
|
|
|
|
eventsChannel: string;
|
|
|
|
|
jobsQueueName: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface S3Configuration {
|
|
|
|
|
endpoint: string;
|
|
|
|
|
accessKey: string;
|
|
|
|
|
secretKey: string;
|
|
|
|
|
bucketName: string;
|
|
|
|
|
region: string;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-05 12:36:40 +01:00
|
|
|
export interface SmtpConfiguration {
|
2025-01-05 12:13:46 +01:00
|
|
|
host: string;
|
|
|
|
|
port: number;
|
|
|
|
|
user: string;
|
|
|
|
|
password: string;
|
2025-01-05 20:25:48 +01:00
|
|
|
from: {
|
|
|
|
|
email: string;
|
|
|
|
|
name: string;
|
|
|
|
|
};
|
2025-01-05 12:13:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AiConfiguration {
|
|
|
|
|
enabled: boolean;
|
|
|
|
|
entryEmbedDelay: number;
|
|
|
|
|
openai: OpenAiConfiguration;
|
|
|
|
|
chunking: ChunkingConfiguration;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface OpenAiConfiguration {
|
|
|
|
|
apiKey: string;
|
|
|
|
|
embeddingModel: string;
|
|
|
|
|
embeddingDimensions: number;
|
|
|
|
|
embeddingBatchSize: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ChunkingConfiguration {
|
|
|
|
|
defaultChunkSize: number;
|
|
|
|
|
defaultOverlap: number;
|
|
|
|
|
enhanceWithContext: boolean;
|
|
|
|
|
contextEnhancerModel: string;
|
|
|
|
|
contextEnhancerTemperature: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getRequiredEnv = (env: string): string => {
|
|
|
|
|
const value = process.env[env];
|
|
|
|
|
if (!value) {
|
|
|
|
|
throw new Error(`${env} is not set`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getOptionalEnv = (env: string): string | undefined => {
|
|
|
|
|
return process.env[env];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const configuration: Configuration = {
|
|
|
|
|
server: {
|
|
|
|
|
name: getRequiredEnv('SERVER_NAME'),
|
|
|
|
|
avatar: getOptionalEnv('SERVER_AVATAR') || '',
|
|
|
|
|
},
|
2025-01-05 20:25:48 +01:00
|
|
|
account: {
|
|
|
|
|
verificationType:
|
|
|
|
|
(getOptionalEnv(
|
|
|
|
|
'ACCOUNT_VERIFICATION_TYPE'
|
|
|
|
|
) as AccountVerificationType) || 'manual',
|
|
|
|
|
otpTimeout: parseInt(getOptionalEnv('ACCOUNT_OTP_TIMEOUT') || '600'),
|
|
|
|
|
allowGoogleLogin: getOptionalEnv('ACCOUNT_ALLOW_GOOGLE_LOGIN') === 'true',
|
|
|
|
|
},
|
2025-01-12 18:25:04 +01:00
|
|
|
user: {
|
|
|
|
|
storageLimit: BigInt(getOptionalEnv('USER_STORAGE_LIMIT') || '10737418240'),
|
|
|
|
|
maxFileSize: BigInt(getOptionalEnv('USER_MAX_FILE_SIZE') || '104857600'),
|
|
|
|
|
},
|
2025-01-05 12:13:46 +01:00
|
|
|
postgres: {
|
|
|
|
|
url: getRequiredEnv('POSTGRES_URL'),
|
|
|
|
|
},
|
|
|
|
|
redis: {
|
|
|
|
|
url: getRequiredEnv('REDIS_URL'),
|
|
|
|
|
db: parseInt(getOptionalEnv('REDIS_DB') || '0'),
|
|
|
|
|
jobsQueueName: getOptionalEnv('REDIS_JOBS_QUEUE_NAME') || 'jobs',
|
|
|
|
|
eventsChannel: getOptionalEnv('REDIS_EVENTS_CHANNEL') || 'events',
|
|
|
|
|
},
|
|
|
|
|
avatarS3: {
|
|
|
|
|
endpoint: getRequiredEnv('S3_AVATARS_ENDPOINT'),
|
|
|
|
|
accessKey: getRequiredEnv('S3_AVATARS_ACCESS_KEY'),
|
|
|
|
|
secretKey: getRequiredEnv('S3_AVATARS_SECRET_KEY'),
|
|
|
|
|
bucketName: getRequiredEnv('S3_AVATARS_BUCKET_NAME'),
|
|
|
|
|
region: getRequiredEnv('S3_AVATARS_REGION'),
|
|
|
|
|
},
|
|
|
|
|
fileS3: {
|
|
|
|
|
endpoint: getRequiredEnv('S3_FILES_ENDPOINT'),
|
|
|
|
|
accessKey: getRequiredEnv('S3_FILES_ACCESS_KEY'),
|
|
|
|
|
secretKey: getRequiredEnv('S3_FILES_SECRET_KEY'),
|
|
|
|
|
bucketName: getRequiredEnv('S3_FILES_BUCKET_NAME'),
|
|
|
|
|
region: getRequiredEnv('S3_FILES_REGION'),
|
|
|
|
|
},
|
2025-01-05 12:36:40 +01:00
|
|
|
smtp: {
|
|
|
|
|
host: getOptionalEnv('SMTP_HOST') || '',
|
|
|
|
|
port: parseInt(getOptionalEnv('SMTP_PORT') || '587'),
|
|
|
|
|
user: getOptionalEnv('SMTP_USER') || '',
|
|
|
|
|
password: getOptionalEnv('SMTP_PASSWORD') || '',
|
2025-01-05 20:25:48 +01:00
|
|
|
from: {
|
|
|
|
|
email: getRequiredEnv('SMTP_EMAIL_FROM'),
|
|
|
|
|
name: getRequiredEnv('SMTP_EMAIL_FROM_NAME'),
|
|
|
|
|
},
|
2025-01-05 12:13:46 +01:00
|
|
|
},
|
|
|
|
|
ai: {
|
|
|
|
|
enabled: getOptionalEnv('AI_ENABLED') === 'true',
|
|
|
|
|
entryEmbedDelay: parseInt(
|
|
|
|
|
getOptionalEnv('AI_ENTRY_EMBED_DELAY') || '60000'
|
|
|
|
|
),
|
|
|
|
|
openai: {
|
|
|
|
|
apiKey: getOptionalEnv('OPENAI_API_KEY') || '',
|
|
|
|
|
embeddingModel: getOptionalEnv('OPENAI_EMBEDDING_MODEL') || '',
|
|
|
|
|
embeddingDimensions: parseInt(
|
|
|
|
|
getOptionalEnv('OPENAI_EMBEDDING_DIMENSIONS') || '2000'
|
|
|
|
|
),
|
|
|
|
|
embeddingBatchSize: parseInt(
|
|
|
|
|
getOptionalEnv('OPENAI_EMBEDDING_BATCH_SIZE') || '50'
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
chunking: {
|
|
|
|
|
defaultChunkSize: parseInt(
|
|
|
|
|
getOptionalEnv('CHUNK_DEFAULT_CHUNK_SIZE') || '1000'
|
|
|
|
|
),
|
|
|
|
|
defaultOverlap: parseInt(
|
|
|
|
|
getOptionalEnv('CHUNK_DEFAULT_OVERLAP') || '200'
|
|
|
|
|
),
|
|
|
|
|
enhanceWithContext:
|
|
|
|
|
getOptionalEnv('CHUNK_ENHANCE_WITH_CONTEXT') === 'true',
|
|
|
|
|
contextEnhancerModel:
|
|
|
|
|
getOptionalEnv('CHUNK_CONTEXT_ENHANCER_MODEL') || 'gpt-4o-mini',
|
|
|
|
|
contextEnhancerTemperature: parseFloat(
|
|
|
|
|
getOptionalEnv('CHUNK_CONTEXT_ENHANCER_TEMPERATURE') || '0.3'
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|