// Notion Database Diagnostics Tool
// Comprehensive testing and validation for Notion integration
import { Client } from '@notionhq/client';
import { validateNotionConfig, testNotionDatabaseConnection } from '../config/notion-config.js';
export class NotionDiagnostics {
constructor() {
this.notion = null;
}
async getNotionClient() {
if (this.notion) return this.notion;
try {
const hostname = process.env.REPLIT_CONNECTORS_HOSTNAME;
const xReplitToken = process.env.REPL_IDENTITY
? 'repl ' + process.env.REPL_IDENTITY
: process.env.WEB_REPL_RENEWAL
? 'depl ' + process.env.WEB_REPL_RENEWAL
: null;
if (!xReplitToken) {
throw new Error('REPLIT_TOKEN not found - ensure you are running in Replit environment');
}
const connectionSettings = await fetch(
'https://' + hostname + '/api/v2/connection?include_secrets=true&connector_names=notion',
{
headers: {
'Accept': 'application/json',
'X_REPLIT_TOKEN': xReplitToken
}
}
).then(res => {
if (!res.ok) {
throw new Error(`HTTP ${res.status}: ${res.statusText}`);
}
return res.json();
}).then(data => data.items?.[0]);
const accessToken = connectionSettings?.settings?.access_token ||
connectionSettings?.settings?.oauth?.credentials?.access_token;
if (!connectionSettings || !accessToken) {
throw new Error('Notion connector not properly configured - please check Replit integrations');
}
this.notion = new Client({ auth: accessToken });
return this.notion;
} catch (error) {
throw new Error(`Failed to initialize Notion client: ${error.message}`);
}
}
async runComprehensiveDiagnostics() {
console.log('๐ RUNNING NOTION INTEGRATION DIAGNOSTICS');
console.log('=========================================\n');
const results = {
configValidation: null,
connectionTest: null,
schemaValidation: null,
operationalTest: null,
overall: { success: false, errors: [], warnings: [] }
};
try {
// Step 1: Configuration Validation
console.log('๐ Step 1: Validating Notion configuration...');
results.configValidation = validateNotionConfig();
if (results.configValidation.isValid) {
console.log('โ
Configuration validation passed');
} else {
console.log('โ Configuration issues found:');
results.configValidation.issues.forEach(issue => console.log(` โข ${issue}`));
results.overall.errors.push(...results.configValidation.issues);
}
if (results.configValidation.warnings?.length > 0) {
console.log('โ ๏ธ Configuration warnings:');
results.configValidation.warnings.forEach(warning => console.log(` โข ${warning}`));
results.overall.warnings.push(...results.configValidation.warnings);
}
// Step 2: Connection Test
console.log('\n๐ Step 2: Testing Notion API connection...');
const notion = await this.getNotionClient();
results.connectionTest = { success: true, message: 'Notion client initialized successfully' };
console.log('โ
Notion API connection successful');
// Step 3: Database Access Test
console.log('\n๐๏ธ Step 3: Testing database access and schema...');
results.schemaValidation = await testNotionDatabaseConnection(notion);
if (results.schemaValidation.success) {
console.log(`โ
Database accessible: "${results.schemaValidation.databaseTitle}"`);
if (results.schemaValidation.schemaValid) {
console.log('โ
Schema validation passed');
} else {
console.log('โ ๏ธ Schema issues found:');
if (results.schemaValidation.missingFields?.length > 0) {
console.log(' Missing fields:');
results.schemaValidation.missingFields.forEach(field => console.log(` - ${field}`));
results.overall.errors.push(`Missing required fields: ${results.schemaValidation.missingFields.join(', ')}`);
}
if (results.schemaValidation.schemaIssues?.length > 0) {
console.log(' Schema type issues:');
results.schemaValidation.schemaIssues.forEach(issue => console.log(` - ${issue}`));
results.overall.errors.push(...results.schemaValidation.schemaIssues);
}
}
} else {
console.log(`โ Database access failed: ${results.schemaValidation.message}`);
results.overall.errors.push(results.schemaValidation.message);
}
// Step 4: Operational Test (try to query characters)
console.log('\n๐ญ Step 4: Testing character query operations...');
try {
const databaseId = results.schemaValidation?.databaseId ||
results.configValidation?.fallbackDatabaseId;
const queryResponse = await notion.databases.query({
database_id: databaseId,
page_size: 1
});
results.operationalTest = {
success: true,
characterCount: queryResponse.results.length,
message: `Successfully queried database - found ${queryResponse.results.length} character(s)`
};
console.log(`โ
Query operation successful - found ${queryResponse.results.length} character(s)`);
} catch (error) {
results.operationalTest = {
success: false,
error: error.message,
message: `Query operation failed: ${error.message}`
};
console.log(`โ Query operation failed: ${error.message}`);
results.overall.errors.push(`Query operation failed: ${error.message}`);
}
} catch (error) {
console.log(`โ Diagnostics failed: ${error.message}`);
results.overall.errors.push(`Diagnostics failed: ${error.message}`);
}
// Overall Assessment
console.log('\n๐ DIAGNOSTIC SUMMARY');
console.log('=====================');
results.overall.success = results.overall.errors.length === 0;
if (results.overall.success) {
console.log('๐ All systems operational!');
} else {
console.log('โ Issues found:');
results.overall.errors.forEach(error => console.log(` โข ${error}`));
}
if (results.overall.warnings.length > 0) {
console.log('โ ๏ธ Warnings:');
results.overall.warnings.forEach(warning => console.log(` โข ${warning}`));
}
// Recommendations
console.log('\n๐ก RECOMMENDATIONS');
console.log('==================');
if (!results.configValidation?.isValid) {
console.log('1. Set the CHARACTERS_MASTER_DB environment variable to your Notion database ID');
console.log(' You can find this in your Notion database URL after /database/');
}
if (!results.schemaValidation?.success) {
console.log('2. Ensure your Notion database exists and is accessible');
console.log('3. Verify the database ID is correct');
}
if (!results.schemaValidation?.schemaValid) {
console.log('4. Update your Notion database to include required fields:');
console.log(' - Character Name (Title field)');
console.log(' - Character Type (Select field)');
console.log(' - Description (Text field)');
console.log(' - Physical Traits (Text field)');
console.log(' - Production Status (Select field)');
}
return results;
}
// Create a minimal test character to verify full integration
async testCharacterCreation() {
console.log('\n๐งช TESTING CHARACTER CREATION');
console.log('==============================');
try {
const notion = await this.getNotionClient();
const databaseId = process.env.CHARACTERS_MASTER_DB || '5b96c172-96b2-4b53-a52c-60d4874779f4';
const testCharacter = {
'Character Name': {
title: [{ text: { content: 'Test Character (Diagnostic)' } }]
},
'Character Type': {
select: { name: 'Test Character' }
},
'Description': {
rich_text: [{ text: { content: 'Diagnostic test character' } }]
},
'Physical Traits': {
rich_text: [{ text: { content: 'Small puppet for testing' } }]
},
'Production Status': {
select: { name: 'Testing' }
}
};
const response = await notion.pages.create({
parent: { database_id: databaseId },
properties: testCharacter
});
console.log('โ
Test character created successfully');
console.log(`๐ Page ID: ${response.id}`);
// Clean up - delete the test character
await notion.pages.update({
page_id: response.id,
archived: true
});
console.log('๐๏ธ Test character cleaned up (archived)');
return {
success: true,
message: 'Character creation test passed',
pageId: response.id
};
} catch (error) {
console.log(`โ Character creation test failed: ${error.message}`);
return {
success: false,
error: error.message,
message: `Character creation test failed: ${error.message}`
};
}
}
}
// Export function for direct use
export async function runNotionDiagnostics() {
const diagnostics = new NotionDiagnostics();
const results = await diagnostics.runComprehensiveDiagnostics();
if (results.overall.success) {
// Run character creation test if basic diagnostics pass
const creationTest = await diagnostics.testCharacterCreation();
results.characterCreationTest = creationTest;
}
return results;
}