|
|
@@ -9,6 +9,10 @@ export interface Site {
|
|
|
url: string;
|
|
|
sitemap_url: string;
|
|
|
site_type: string;
|
|
|
+ site_platform: string;
|
|
|
+ custom_sitemap_url: string | null;
|
|
|
+ max_crawl_depth: number;
|
|
|
+ max_pages: number;
|
|
|
qdrant_enabled: boolean;
|
|
|
deleted_at: string | null; // Soft delete timestamp
|
|
|
created_at: string;
|
|
|
@@ -152,6 +156,7 @@ export class SiteDatabase {
|
|
|
|
|
|
this.db = new Database(dbPath);
|
|
|
this.migrateShopsToSites();
|
|
|
+ this.migrateSiteTypeToPlatform();
|
|
|
this.initializeTables();
|
|
|
logger.info(`Database initialized at ${dbPath}`);
|
|
|
}
|
|
|
@@ -185,6 +190,33 @@ export class SiteDatabase {
|
|
|
logger.info('Database migration complete: shops to sites');
|
|
|
}
|
|
|
|
|
|
+ private migrateSiteTypeToPlatform(): void {
|
|
|
+ // Check if site_platform column already exists
|
|
|
+ const columns = this.db.pragma('table_info(sites)') as any[];
|
|
|
+ const hasSitePlatform = columns.some((col: any) => col.name === 'site_platform');
|
|
|
+ if (hasSitePlatform) return;
|
|
|
+
|
|
|
+ logger.info('Migrating database: adding site_platform and related columns');
|
|
|
+
|
|
|
+ this.db.exec(`ALTER TABLE sites ADD COLUMN site_platform TEXT NOT NULL DEFAULT 'generic'`);
|
|
|
+ this.db.exec(`ALTER TABLE sites ADD COLUMN custom_sitemap_url TEXT`);
|
|
|
+ this.db.exec(`ALTER TABLE sites ADD COLUMN max_crawl_depth INTEGER NOT NULL DEFAULT 3`);
|
|
|
+ this.db.exec(`ALTER TABLE sites ADD COLUMN max_pages INTEGER NOT NULL DEFAULT 200`);
|
|
|
+
|
|
|
+ // Move platform values from site_type to site_platform
|
|
|
+ this.db.exec(`
|
|
|
+ UPDATE sites SET site_platform = site_type, site_type = 'webshop'
|
|
|
+ WHERE site_type IN ('shoprenter', 'woocommerce', 'shopify')
|
|
|
+ `);
|
|
|
+ // Remaining rows get site_type = 'website' where site_platform is still 'generic'
|
|
|
+ this.db.exec(`
|
|
|
+ UPDATE sites SET site_type = 'website'
|
|
|
+ WHERE site_platform = 'generic' AND site_type NOT IN ('webshop', 'website')
|
|
|
+ `);
|
|
|
+
|
|
|
+ logger.info('Database migration complete: site_platform columns added');
|
|
|
+ }
|
|
|
+
|
|
|
private initializeTables(): void {
|
|
|
// Sites table
|
|
|
this.db.exec(`
|
|
|
@@ -194,6 +226,10 @@ export class SiteDatabase {
|
|
|
url TEXT NOT NULL UNIQUE,
|
|
|
sitemap_url TEXT NOT NULL,
|
|
|
site_type TEXT NOT NULL,
|
|
|
+ site_platform TEXT NOT NULL DEFAULT 'generic',
|
|
|
+ custom_sitemap_url TEXT,
|
|
|
+ max_crawl_depth INTEGER NOT NULL DEFAULT 3,
|
|
|
+ max_pages INTEGER NOT NULL DEFAULT 200,
|
|
|
qdrant_enabled INTEGER DEFAULT 0,
|
|
|
deleted_at TEXT,
|
|
|
created_at TEXT NOT NULL,
|
|
|
@@ -474,18 +510,28 @@ export class SiteDatabase {
|
|
|
}
|
|
|
|
|
|
// Site operations
|
|
|
- createSite(url: string, sitemapUrl: string, sitePlatform: string, customId?: string, qdrantEnabled?: boolean): Site {
|
|
|
+ createSite(
|
|
|
+ url: string,
|
|
|
+ sitemapUrl: string,
|
|
|
+ sitePlatform: string,
|
|
|
+ customId?: string,
|
|
|
+ qdrantEnabled?: boolean,
|
|
|
+ siteType?: string,
|
|
|
+ customSitemapUrl?: string | null
|
|
|
+ ): Site {
|
|
|
const id = uuidv4();
|
|
|
const now = new Date().toISOString();
|
|
|
const custom_id = customId || null;
|
|
|
const qdrant_enabled = qdrantEnabled !== undefined ? qdrantEnabled : true; // Default true for new sites
|
|
|
+ const resolvedSiteType = siteType || (sitePlatform === 'generic' ? 'website' : 'webshop');
|
|
|
+ const resolvedCustomSitemap = customSitemapUrl ?? null;
|
|
|
|
|
|
const stmt = this.db.prepare(`
|
|
|
- INSERT INTO sites (id, custom_id, url, sitemap_url, site_type, qdrant_enabled, deleted_at, created_at, updated_at)
|
|
|
- VALUES (?, ?, ?, ?, ?, ?, NULL, ?, ?)
|
|
|
+ INSERT INTO sites (id, custom_id, url, sitemap_url, site_type, site_platform, custom_sitemap_url, max_crawl_depth, max_pages, qdrant_enabled, deleted_at, created_at, updated_at)
|
|
|
+ VALUES (?, ?, ?, ?, ?, ?, ?, 3, 200, ?, NULL, ?, ?)
|
|
|
`);
|
|
|
|
|
|
- stmt.run(id, custom_id, url, sitemapUrl, sitePlatform, qdrant_enabled ? 1 : 0, now, now);
|
|
|
+ stmt.run(id, custom_id, url, sitemapUrl, resolvedSiteType, sitePlatform, resolvedCustomSitemap, qdrant_enabled ? 1 : 0, now, now);
|
|
|
|
|
|
// Initialize analytics for this site
|
|
|
this.db.prepare(`
|
|
|
@@ -500,7 +546,11 @@ export class SiteDatabase {
|
|
|
custom_id,
|
|
|
url,
|
|
|
sitemap_url: sitemapUrl,
|
|
|
- site_type: sitePlatform,
|
|
|
+ site_type: resolvedSiteType,
|
|
|
+ site_platform: sitePlatform,
|
|
|
+ custom_sitemap_url: resolvedCustomSitemap,
|
|
|
+ max_crawl_depth: 3,
|
|
|
+ max_pages: 200,
|
|
|
qdrant_enabled,
|
|
|
deleted_at: null,
|
|
|
created_at: now,
|
|
|
@@ -551,6 +601,10 @@ export class SiteDatabase {
|
|
|
s.url,
|
|
|
s.sitemap_url,
|
|
|
s.site_type,
|
|
|
+ s.site_platform,
|
|
|
+ s.custom_sitemap_url,
|
|
|
+ s.max_crawl_depth,
|
|
|
+ s.max_pages,
|
|
|
s.qdrant_enabled,
|
|
|
s.deleted_at,
|
|
|
s.created_at,
|
|
|
@@ -589,6 +643,10 @@ export class SiteDatabase {
|
|
|
url: row.url,
|
|
|
sitemap_url: row.sitemap_url,
|
|
|
site_type: row.site_type,
|
|
|
+ site_platform: row.site_platform,
|
|
|
+ custom_sitemap_url: row.custom_sitemap_url,
|
|
|
+ max_crawl_depth: row.max_crawl_depth,
|
|
|
+ max_pages: row.max_pages,
|
|
|
qdrant_enabled: Boolean(row.qdrant_enabled),
|
|
|
deleted_at: row.deleted_at,
|
|
|
created_at: row.created_at,
|
|
|
@@ -623,6 +681,47 @@ export class SiteDatabase {
|
|
|
`).run(...values);
|
|
|
}
|
|
|
|
|
|
+ updateSiteSettings(siteId: string, settings: {
|
|
|
+ site_type?: string;
|
|
|
+ site_platform?: string;
|
|
|
+ custom_sitemap_url?: string | null;
|
|
|
+ max_crawl_depth?: number;
|
|
|
+ max_pages?: number;
|
|
|
+ }): void {
|
|
|
+ const now = new Date().toISOString();
|
|
|
+ const setClauses: string[] = ['updated_at = ?'];
|
|
|
+ const values: any[] = [now];
|
|
|
+
|
|
|
+ if (settings.site_type !== undefined) {
|
|
|
+ setClauses.push('site_type = ?');
|
|
|
+ values.push(settings.site_type);
|
|
|
+ }
|
|
|
+ if (settings.site_platform !== undefined) {
|
|
|
+ setClauses.push('site_platform = ?');
|
|
|
+ values.push(settings.site_platform);
|
|
|
+ }
|
|
|
+ if (settings.custom_sitemap_url !== undefined) {
|
|
|
+ setClauses.push('custom_sitemap_url = ?');
|
|
|
+ values.push(settings.custom_sitemap_url);
|
|
|
+ }
|
|
|
+ if (settings.max_crawl_depth !== undefined) {
|
|
|
+ setClauses.push('max_crawl_depth = ?');
|
|
|
+ values.push(settings.max_crawl_depth);
|
|
|
+ }
|
|
|
+ if (settings.max_pages !== undefined) {
|
|
|
+ setClauses.push('max_pages = ?');
|
|
|
+ values.push(settings.max_pages);
|
|
|
+ }
|
|
|
+
|
|
|
+ values.push(siteId);
|
|
|
+
|
|
|
+ this.db.prepare(`
|
|
|
+ UPDATE sites SET ${setClauses.join(', ')} WHERE id = ?
|
|
|
+ `).run(...values);
|
|
|
+
|
|
|
+ logger.info(`Updated settings for site ${siteId}`);
|
|
|
+ }
|
|
|
+
|
|
|
// Method to set/update custom_id for a site
|
|
|
setCustomId(identifier: string, customId: string | null): boolean {
|
|
|
const site = this.getSiteByAnyId(identifier);
|