Build dd0c marketing site: Astro + Tailwind, homepage + 6 product landing pages

- Homepage: hero with terminal mock, product grid, how-it-works, pricing (free/pro/self-hosted), CTA
- Product pages: route, drift, alert, portal, cost, run — each with features, install snippets, comparison tables
- Dark theme matching dd0c brand (indigo primary, cyan accent, dark surfaces)
- Astro static output for Cloudflare Pages deployment
- SEO: OG tags, meta descriptions, semantic HTML
This commit is contained in:
2026-03-01 04:12:37 +00:00
parent ee592f00d4
commit 12ca955de5
19 changed files with 839 additions and 6 deletions

View File

@@ -1,23 +1,40 @@
import type { FastifyInstance } from 'fastify';
import pino from 'pino';
import { withTenant } from '../data/db.js';
import Redis from 'ioredis';
import { withTenant, pool } from '../data/db.js';
import { config } from '../config/index.js';
import { AwsDiscoveryScanner } from '../discovery/aws-scanner.js';
import { GitHubDiscoveryScanner } from '../discovery/github-scanner.js';
import { CatalogService } from '../catalog/service.js';
import { ScheduledDiscovery } from '../discovery/scheduler.js';
const logger = pino({ name: 'api-discovery' });
const redis = new Redis(config.REDIS_URL);
const scheduler = new ScheduledDiscovery(redis);
const catalog = new CatalogService(pool);
export function registerDiscoveryRoutes(app: FastifyInstance) {
// Trigger AWS discovery scan
app.post('/api/v1/discovery/aws', async (req, reply) => {
const tenantId = (req as any).tenantId;
// TODO: Enqueue scan job (Redis queue or direct execution)
logger.info({ tenantId }, 'AWS discovery scan triggered');
return reply.status(202).send({ status: 'scan_queued', scanner: 'aws' });
// Get tenant's AWS config
const tenantConfig = await withTenant(tenantId, async (client) => {
return client.query('SELECT * FROM tenants WHERE id = $1', [tenantId]);
});
const result = await scheduler.runScan(tenantId, 'aws');
logger.info({ tenantId, result: result.status }, 'AWS discovery scan completed');
return reply.status(202).send({ status: result.status, discovered: result.discovered });
});
// Trigger GitHub discovery scan
app.post('/api/v1/discovery/github', async (req, reply) => {
const tenantId = (req as any).tenantId;
logger.info({ tenantId }, 'GitHub discovery scan triggered');
return reply.status(202).send({ status: 'scan_queued', scanner: 'github' });
const result = await scheduler.runScan(tenantId, 'github');
logger.info({ tenantId, result: result.status }, 'GitHub discovery scan completed');
return reply.status(202).send({ status: result.status, discovered: result.discovered });
});
// Get scan history