From 12ca955de57be658ceca7ce6cbf8402d5475b2a9 Mon Sep 17 00:00:00 2001 From: Max Mayfield Date: Sun, 1 Mar 2026 04:12:37 +0000 Subject: [PATCH] Build dd0c marketing site: Astro + Tailwind, homepage + 6 product landing pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- .../04-lightweight-idp/src/api/discovery.ts | 29 ++++-- products/marketing/site/astro.config.mjs | 8 ++ products/marketing/site/package.json | 15 +++ .../marketing/site/src/components/CTA.astro | 17 ++++ .../site/src/components/Footer.astro | 50 ++++++++++ .../marketing/site/src/components/Hero.astro | 51 ++++++++++ .../site/src/components/HowItWorks.astro | 42 ++++++++ .../site/src/components/Layout.astro | 53 +++++++++++ .../site/src/components/Pricing.astro | 91 ++++++++++++++++++ .../site/src/components/Products.astro | 86 +++++++++++++++++ products/marketing/site/src/pages/alert.astro | 49 ++++++++++ products/marketing/site/src/pages/cost.astro | 49 ++++++++++ products/marketing/site/src/pages/drift.astro | 52 ++++++++++ products/marketing/site/src/pages/index.astro | 18 ++++ .../marketing/site/src/pages/portal.astro | 44 +++++++++ products/marketing/site/src/pages/route.astro | 95 +++++++++++++++++++ products/marketing/site/src/pages/run.astro | 64 +++++++++++++ products/marketing/site/tailwind.config.mjs | 26 +++++ products/marketing/site/tsconfig.json | 6 ++ 19 files changed, 839 insertions(+), 6 deletions(-) create mode 100644 products/marketing/site/astro.config.mjs create mode 100644 products/marketing/site/package.json create mode 100644 products/marketing/site/src/components/CTA.astro create mode 100644 products/marketing/site/src/components/Footer.astro create mode 100644 products/marketing/site/src/components/Hero.astro create mode 100644 products/marketing/site/src/components/HowItWorks.astro create mode 100644 products/marketing/site/src/components/Layout.astro create mode 100644 products/marketing/site/src/components/Pricing.astro create mode 100644 products/marketing/site/src/components/Products.astro create mode 100644 products/marketing/site/src/pages/alert.astro create mode 100644 products/marketing/site/src/pages/cost.astro create mode 100644 products/marketing/site/src/pages/drift.astro create mode 100644 products/marketing/site/src/pages/index.astro create mode 100644 products/marketing/site/src/pages/portal.astro create mode 100644 products/marketing/site/src/pages/route.astro create mode 100644 products/marketing/site/src/pages/run.astro create mode 100644 products/marketing/site/tailwind.config.mjs create mode 100644 products/marketing/site/tsconfig.json diff --git a/products/04-lightweight-idp/src/api/discovery.ts b/products/04-lightweight-idp/src/api/discovery.ts index 800c9d8..4fde9be 100644 --- a/products/04-lightweight-idp/src/api/discovery.ts +++ b/products/04-lightweight-idp/src/api/discovery.ts @@ -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 diff --git a/products/marketing/site/astro.config.mjs b/products/marketing/site/astro.config.mjs new file mode 100644 index 0000000..87ffefe --- /dev/null +++ b/products/marketing/site/astro.config.mjs @@ -0,0 +1,8 @@ +import { defineConfig } from 'astro/config'; +import tailwind from '@astrojs/tailwind'; + +export default defineConfig({ + integrations: [tailwind()], + output: 'static', + site: 'https://dd0c.dev', +}); diff --git a/products/marketing/site/package.json b/products/marketing/site/package.json new file mode 100644 index 0000000..b63d0cf --- /dev/null +++ b/products/marketing/site/package.json @@ -0,0 +1,15 @@ +{ + "name": "dd0c-site", + "type": "module", + "version": "0.1.0", + "scripts": { + "dev": "astro dev", + "build": "astro build", + "preview": "astro preview" + }, + "dependencies": { + "astro": "^4.10.0", + "@astrojs/tailwind": "^5.1.0", + "tailwindcss": "^3.4.0" + } +} diff --git a/products/marketing/site/src/components/CTA.astro b/products/marketing/site/src/components/CTA.astro new file mode 100644 index 0000000..2640136 --- /dev/null +++ b/products/marketing/site/src/components/CTA.astro @@ -0,0 +1,17 @@ +--- +--- + +
+
+

Stop paying enterprise prices
for tools you half-use

+

+ dd0c is built by a solo engineer who got tired of $50K/year DevOps platforms + that take 3 months to set up. Each tool does one thing well. Start free. Pay when it saves you money. +

+ +
+
diff --git a/products/marketing/site/src/components/Footer.astro b/products/marketing/site/src/components/Footer.astro new file mode 100644 index 0000000..a4ecb2b --- /dev/null +++ b/products/marketing/site/src/components/Footer.astro @@ -0,0 +1,50 @@ +--- +--- + + diff --git a/products/marketing/site/src/components/Hero.astro b/products/marketing/site/src/components/Hero.astro new file mode 100644 index 0000000..ed16dbf --- /dev/null +++ b/products/marketing/site/src/components/Hero.astro @@ -0,0 +1,51 @@ +--- +--- + +
+
+
+ + Now in beta — free while we ship +
+ +

+ DevOps tools that
+ don't waste your time +

+ +

+ Six focused tools for the problems you actually have. + Route LLM costs. Detect drift. Correlate alerts. Catalog services. Catch cost spikes. Automate runbooks. +

+ + + +
+
+
+
+ + + + terminal +
+
$ curl -s https://api.dd0c.dev/health | jq
+{
+  "route": "healthy",
+  "drift": "healthy",
+  "alert": "healthy",
+  "portal": "healthy",
+  "cost": "healthy",
+  "run": "healthy"
+}
+
+
+
+
diff --git a/products/marketing/site/src/components/HowItWorks.astro b/products/marketing/site/src/components/HowItWorks.astro new file mode 100644 index 0000000..c416697 --- /dev/null +++ b/products/marketing/site/src/components/HowItWorks.astro @@ -0,0 +1,42 @@ +--- +const steps = [ + { + num: '01', + title: 'Sign up in 30 seconds', + description: 'Email and password. No credit card. No sales call. No "schedule a demo" button.', + }, + { + num: '02', + title: 'Connect your stuff', + description: 'AWS credentials, Terraform state, PagerDuty webhook, GitHub org — whatever the tool needs. 5-minute setup guides.', + }, + { + num: '03', + title: 'See results immediately', + description: 'First drift scan in under a minute. First cost baseline in an hour. First correlated incident the next time your pager fires.', + }, +]; +--- + +
+
+
+

How it works

+

No enterprise onboarding. No professional services.

+
+ +
+ {steps.map((step) => ( +
+
+ {step.num} +
+
+

{step.title}

+

{step.description}

+
+
+ ))} +
+
+
diff --git a/products/marketing/site/src/components/Layout.astro b/products/marketing/site/src/components/Layout.astro new file mode 100644 index 0000000..af07f85 --- /dev/null +++ b/products/marketing/site/src/components/Layout.astro @@ -0,0 +1,53 @@ +--- +interface Props { + title: string; + description?: string; +} + +const { title, description = 'Six DevOps tools. One platform. Built for teams that ship.' } = Astro.props; +--- + + + + + + + + + + + + + + + + + + + + + {title} + + + +
+ +
+ + diff --git a/products/marketing/site/src/components/Pricing.astro b/products/marketing/site/src/components/Pricing.astro new file mode 100644 index 0000000..2bd4676 --- /dev/null +++ b/products/marketing/site/src/components/Pricing.astro @@ -0,0 +1,91 @@ +--- +const plans = [ + { + name: 'Free', + price: '$0', + period: 'forever', + description: 'Try any tool with generous limits.', + features: [ + 'All 6 tools included', + '1 connected account per tool', + '10K events/month (alert)', + '50 services (portal)', + '7-day data retention', + 'Community support', + ], + cta: 'Start free', + ctaLink: 'https://app.dd0c.dev/signup', + highlight: false, + }, + { + name: 'Pro', + price: 'From $19', + period: '/mo per tool', + description: 'Pay only for what you use. Mix and match.', + features: [ + 'Unlimited connected accounts', + 'Unlimited events', + 'Unlimited services', + '90-day data retention', + 'Slack + email notifications', + 'API access + webhooks', + 'Priority support', + ], + cta: 'Start free, upgrade later', + ctaLink: 'https://app.dd0c.dev/signup', + highlight: true, + }, + { + name: 'Self-hosted', + price: '$0', + period: 'your infra', + description: 'Run the whole stack on your own servers.', + features: [ + 'Docker Compose one-liner', + 'All 6 tools included', + 'Unlimited everything', + 'Your data stays on your network', + 'Auto-TLS via Caddy', + 'Community support', + ], + cta: 'View setup guide', + ctaLink: 'https://docs.dd0c.dev/self-hosted', + highlight: false, + }, +]; +--- + +
+
+
+

Simple pricing

+

Free tier is real. No "contact sales" trap.

+
+ +
+ {plans.map((plan) => ( +
+

{plan.name}

+
+ {plan.price} + {plan.period} +
+

{plan.description}

+ +
    + {plan.features.map((f) => ( +
  • + + {f} +
  • + ))} +
+ + + {plan.cta} + +
+ ))} +
+
+
diff --git a/products/marketing/site/src/components/Products.astro b/products/marketing/site/src/components/Products.astro new file mode 100644 index 0000000..3d6deec --- /dev/null +++ b/products/marketing/site/src/components/Products.astro @@ -0,0 +1,86 @@ +--- +const products = [ + { + name: 'route', + tagline: 'LLM Cost Router', + description: 'Route AI API calls to the cheapest provider automatically. Set cost caps, get usage dashboards, stop burning money on GPT-4 when GPT-3.5 works fine.', + price: '$49/mo', + icon: '🔀', + keywords: ['llm cost optimization', 'ai api router', 'openai cost management'], + color: 'from-violet-500 to-purple-600', + }, + { + name: 'drift', + tagline: 'IaC Drift Detection', + description: 'Lightweight agent scans your Terraform state, detects drift, scrubs secrets, and alerts your team on Slack. No ClickOps surprises.', + price: '$29/stack/mo', + icon: '🔍', + keywords: ['terraform drift detection', 'infrastructure drift', 'iac compliance'], + color: 'from-cyan-500 to-blue-600', + }, + { + name: 'alert', + tagline: 'Alert Intelligence', + description: 'Correlate alerts from PagerDuty, Datadog, OpsGenie, and Grafana into incidents. Cut noise by 80%. Stop waking up for duplicates.', + price: '$39/mo', + icon: '🔔', + keywords: ['alert fatigue', 'alert correlation', 'pagerduty alternative'], + color: 'from-amber-500 to-orange-600', + }, + { + name: 'portal', + tagline: 'Service Catalog', + description: 'Auto-discover services from AWS and GitHub. Know who owns what. Search everything. No more "who runs this Lambda?"', + price: '$29/mo', + icon: '📋', + keywords: ['service catalog', 'internal developer portal', 'backstage alternative'], + color: 'from-emerald-500 to-green-600', + }, + { + name: 'cost', + tagline: 'AWS Cost Anomaly', + description: 'Statistical anomaly detection on your AWS bill. Welford baselines, z-score alerts, Slack notifications before the bill lands.', + price: '$19/account/mo', + icon: '💰', + keywords: ['aws cost anomaly', 'cloud cost monitoring', 'aws billing alerts'], + color: 'from-rose-500 to-pink-600', + }, + { + name: 'run', + tagline: 'Runbook Automation', + description: 'Write runbooks in YAML. Classify commands by safety. Destructive ops require Slack approval. Full audit trail.', + price: '$39/mo', + icon: '⚡', + keywords: ['runbook automation', 'incident response automation', 'rundeck alternative'], + color: 'from-indigo-500 to-blue-600', + }, +]; +--- + +
+
+
+

Six tools. One login.

+

Use one. Use all. Each works standalone.

+
+ + +
+
diff --git a/products/marketing/site/src/pages/alert.astro b/products/marketing/site/src/pages/alert.astro new file mode 100644 index 0000000..67fe5bf --- /dev/null +++ b/products/marketing/site/src/pages/alert.astro @@ -0,0 +1,49 @@ +--- +import Layout from '../components/Layout.astro'; +import Footer from '../components/Footer.astro'; +import CTA from '../components/CTA.astro'; +--- + + +
+
+
+ dd0c/alert +

Alert fatigue is a bug, not a feature

+

+ Ingest webhooks from PagerDuty, Datadog, OpsGenie, and Grafana. Group related alerts into incidents using time-window correlation. Stop waking up three times for the same outage. +

+
+ + + +
+
+
🔗
+

Multi-source correlation

+

HMAC-verified webhooks from 4 providers. Canonical alert schema normalizes everything into one format.

+
+
+
⏱️
+

Time-window grouping

+

5-minute correlation windows. Late alerts attach to existing incidents. Very late alerts create new ones.

+
+
+
📉
+

80% noise reduction

+

20 alerts from the same root cause become 1 incident. Your on-call engineer sees one notification, not twenty.

+
+
+
📧
+

Slack, email, webhook

+

Severity-gated notifications. Critical goes to Slack + email. Low goes to a dashboard. You decide.

+
+
+
+
+ +