feat: SEO template library, discovery pipeline, and orchestrator enhancements

## SEO Template Library
- Add complete template library with 7 page types (state, city, category, brand, product, search, regeneration)
- Add Template Library tab in SEO Orchestrator with accordion-based editors
- Add template preview, validation, and variable injection engine
- Add API endpoints: /api/seo/templates, preview, validate, generate, regenerate

## Discovery Pipeline
- Add promotion.ts for discovery location validation and promotion
- Add discover-all-states.ts script for multi-state discovery
- Add promotion log migration (067)
- Enhance discovery routes and types

## Orchestrator & Admin
- Add crawl_enabled filter to stores page
- Add API permissions page
- Add job queue management
- Add price analytics routes
- Add markets and intelligence routes
- Enhance dashboard and worker monitoring

## Infrastructure
- Add migrations for worker definitions, SEO settings, field alignment
- Add canonical pipeline for scraper v2
- Update hydration and sync orchestrator
- Enhance multi-state query service

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Kelly
2025-12-09 00:05:34 -07:00
parent 9711d594db
commit 2f483b3084
83 changed files with 16700 additions and 1277 deletions

View File

@@ -13,7 +13,15 @@ dotenv.config();
const app = express();
const PORT = process.env.PORT || 3010;
app.use(cors());
// CORS configuration - allow requests from any origin with API key auth
// WordPress plugins need to make requests from their own domains
app.use(cors({
origin: true, // Reflect the request origin
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization', 'x-api-key', 'X-API-Key'],
exposedHeaders: ['Content-Length', 'X-Request-Id'],
}));
app.use(express.json());
// Serve static images when MinIO is not configured
@@ -67,7 +75,11 @@ import publicApiRoutes from './routes/public-api';
import usersRoutes from './routes/users';
import staleProcessesRoutes from './routes/stale-processes';
import orchestratorAdminRoutes from './routes/orchestrator-admin';
import adminDebugRoutes from './routes/admin-debug';
import intelligenceRoutes from './routes/intelligence';
import marketsRoutes from './routes/markets';
import workersRoutes from './routes/workers';
import jobQueueRoutes from './routes/job-queue';
import { createMultiStateRoutes } from './multi-state';
import { trackApiUsage, checkRateLimit } from './middleware/apiTokenTracker';
import { validateWordPressPermissions } from './middleware/wordpressPermissions';
@@ -77,6 +89,7 @@ import { createPortalRoutes } from './portals';
import { createStatesRouter } from './routes/states';
import { createAnalyticsV2Router } from './routes/analytics-v2';
import { createDiscoveryRoutes } from './discovery';
import pipelineRoutes from './routes/pipeline';
import { getPool } from './db/pool';
// Consumer API routes (findadispo.com, findagram.co)
@@ -88,6 +101,7 @@ import consumerDealsRoutes from './routes/consumer-deals';
import eventsRoutes from './routes/events';
import clickAnalyticsRoutes from './routes/click-analytics';
import seoRoutes from './routes/seo';
import priceAnalyticsRoutes from './routes/price-analytics';
// Mark requests from trusted domains (cannaiq.co, findagram.co, findadispo.com)
// These domains can access the API without authentication
@@ -135,6 +149,18 @@ app.use('/api/stale-processes', staleProcessesRoutes);
// Admin routes - orchestrator actions
app.use('/api/admin/orchestrator', orchestratorAdminRoutes);
// Admin routes - debug endpoints (snapshot inspection)
app.use('/api/admin/debug', adminDebugRoutes);
console.log('[AdminDebug] Routes registered at /api/admin/debug');
// Admin routes - intelligence (brands, pricing analytics)
app.use('/api/admin/intelligence', intelligenceRoutes);
console.log('[Intelligence] Routes registered at /api/admin/intelligence');
// Markets routes - store and product data for admin dashboard
app.use('/api/markets', marketsRoutes);
console.log('[Markets] Routes registered at /api/markets');
// SEO orchestrator routes
app.use('/api/seo', seoRoutes);
@@ -142,7 +168,9 @@ app.use('/api/seo', seoRoutes);
app.use('/api/workers', workersRoutes);
// Monitor routes - aliased from workers for convenience
app.use('/api/monitor', workersRoutes);
console.log('[Workers] Routes registered at /api/workers and /api/monitor');
// Job queue management
app.use('/api/job-queue', jobQueueRoutes);
console.log('[Workers] Routes registered at /api/workers, /api/monitor, and /api/job-queue');
// Phase 3: Analytics V2 - Enhanced analytics with rec/med state segmentation
try {
@@ -176,6 +204,10 @@ console.log('[Events] Routes registered at /api/events');
app.use('/api/analytics/clicks', clickAnalyticsRoutes);
console.log('[ClickAnalytics] Routes registered at /api/analytics/clicks');
// Price Analytics API - price history, specials, and market comparisons
app.use('/api/analytics/price', priceAnalyticsRoutes);
console.log('[PriceAnalytics] Routes registered at /api/analytics/price');
// States API routes - cannabis legalization status and targeting
try {
const statesRouter = createStatesRouter(getPool());
@@ -215,6 +247,10 @@ try {
console.warn('[Discovery] Failed to register routes:', error);
}
// Pipeline Stage Transitions - Explicit API for moving stores through 6-stage pipeline
app.use('/api/pipeline', pipelineRoutes);
console.log('[Pipeline] Routes registered at /api/pipeline');
// Platform-specific Discovery Routes
// TODO: Rebuild with /platforms/dutchie/ module