From 6e1dbc1ec7db4346d55b2cc579171963d2e75749 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Sat, 4 Apr 2026 07:56:34 -0700 Subject: [PATCH] =?UTF-8?q?feat(seo):=20=E2=9C=A8=20Introduce=20shared=20u?= =?UTF-8?q?tility=20for=20meta=20tag=20generation=20and=20URL=20slug=20val?= =?UTF-8?q?idation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- features/seo/shared/src/index.ts | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/features/seo/shared/src/index.ts b/features/seo/shared/src/index.ts index 17c334c81..5a25e3596 100755 --- a/features/seo/shared/src/index.ts +++ b/features/seo/shared/src/index.ts @@ -309,6 +309,45 @@ export interface SEOBatchGenerateResponse { progress?: number; } +// ============================================================================ +// CRAWLER DETECTION +// ============================================================================ + +/** + * Known search engine crawler identifiers. + * 'other' captures bots that match crawler patterns but aren't in the known list. + */ +export type CrawlerType = + | 'googlebot' + | 'bingbot' + | 'ahrefsbot' + | 'semrushbot' + | 'dotbot' + | 'mj12bot' + | 'yandexbot' + | 'other'; + +/** + * Payload for SEO_PAGE_SERVED domain event. + * Emitted when a crawler accesses an SEO page. + */ +export interface SeoPageServedPayload { + /** Detected crawler type */ + crawler: CrawlerType; + /** Domain the page was served from */ + domain: string; + /** URL path of the served page */ + path: string; + /** Campaign ID if the path maps to an active campaign target */ + campaignId?: string; + /** Raw User-Agent string */ + userAgent: string; + /** ISO 3166-1 alpha-2 country code (from GeoIP or header) */ + country?: string; + /** Timestamp when the page was served */ + servedAt: string; +} + // ============================================================================ // CONTENT MATURITY // ============================================================================