mirror of
https://github.com/DevVoxel/VectorDNS.git
synced 2026-02-27 05:47:38 +00:00
Add documentation pages with interactive architecture diagram
- /docs route with sidebar navigation and index page - Architecture section: system overview with React Flow diagram, data flow, database schema - API reference, configuration guide, and self-hosting docs for Go DNS server - Feature planning document for future development - Added docs link to landing page nav
This commit is contained in:
215
app/docs/architecture/page.tsx
Normal file
215
app/docs/architecture/page.tsx
Normal file
@@ -0,0 +1,215 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Layers, Globe, Server, Database } from "lucide-react";
|
||||
import { ArchitectureDiagram } from "@/components/docs/architecture-diagram";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
CardDescription,
|
||||
} from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "System Overview",
|
||||
};
|
||||
|
||||
const services = [
|
||||
{
|
||||
icon: Globe,
|
||||
title: "Next.js (Vercel)",
|
||||
badge: "Frontend",
|
||||
badgeVariant: "secondary" as const,
|
||||
items: [
|
||||
"All UI rendering (SSR + client)",
|
||||
"Authentication via Supabase",
|
||||
"WHOIS lookups (whoiser library)",
|
||||
"Domain availability checks (IANA RDAP)",
|
||||
"Dashboard, notifications, settings pages",
|
||||
"Proxies DNS queries to the Go service",
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: Server,
|
||||
title: "Go Microservice (VPS)",
|
||||
badge: "DNS API",
|
||||
badgeVariant: "outline" as const,
|
||||
items: [
|
||||
"DNS record lookups via miekg/dns (UDP/TCP, not DoH)",
|
||||
"Query specific or authoritative nameservers directly",
|
||||
"DNSSEC validation",
|
||||
"DNS propagation checking across multiple resolvers",
|
||||
"Scheduled monitoring (native cron, no serverless time limits)",
|
||||
"Change detection (diff DNS snapshots, notify on changes)",
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: Database,
|
||||
title: "Supabase",
|
||||
badge: "Database & Auth",
|
||||
badgeVariant: "secondary" as const,
|
||||
items: [
|
||||
"Managed Postgres database",
|
||||
"Auth (OAuth + email/password + magic link)",
|
||||
"Row Level Security (RLS) for data isolation",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const tradeoffs = [
|
||||
{
|
||||
concern: "Frontend hosting, SSR, auth",
|
||||
solution: "Vercel (serverless, zero-ops)",
|
||||
},
|
||||
{
|
||||
concern: "DNS resolution, monitoring",
|
||||
solution: "Go on VPS (persistent process, no cold starts)",
|
||||
},
|
||||
{
|
||||
concern: "Database, auth state",
|
||||
solution: "Supabase (managed Postgres)",
|
||||
},
|
||||
];
|
||||
|
||||
const goAdvantages = [
|
||||
"Direct UDP/TCP DNS queries — faster, no middleman",
|
||||
"Can query authoritative nameservers directly",
|
||||
"Supports DNSSEC validation, AXFR, propagation checks",
|
||||
"No cold starts, consistent latency",
|
||||
"No Vercel function timeout limits for monitoring jobs",
|
||||
];
|
||||
|
||||
export default function ArchitectureOverviewPage() {
|
||||
return (
|
||||
<div className="space-y-10">
|
||||
{/* Page header */}
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Layers className="size-6 text-primary" />
|
||||
<h1 className="text-3xl font-bold tracking-tight">System Overview</h1>
|
||||
</div>
|
||||
<p className="text-lg text-muted-foreground">
|
||||
VectorDNS uses a hybrid architecture: a Next.js frontend on Vercel and
|
||||
a Go DNS microservice on a VPS, backed by Supabase for auth and
|
||||
storage.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
{/* Architecture diagram */}
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-xl font-semibold tracking-tight">
|
||||
Architecture Diagram
|
||||
</h2>
|
||||
<ArchitectureDiagram />
|
||||
</div>
|
||||
|
||||
{/* Services */}
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-xl font-semibold tracking-tight">
|
||||
What Each Service Handles
|
||||
</h2>
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
{services.map((service) => (
|
||||
<Card key={service.title}>
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<service.icon className="mt-0.5 size-5 text-primary" />
|
||||
<Badge variant={service.badgeVariant}>{service.badge}</Badge>
|
||||
</div>
|
||||
<CardTitle className="text-base">{service.title}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ul className="space-y-1.5 text-sm text-muted-foreground">
|
||||
{service.items.map((item) => (
|
||||
<li key={item} className="flex gap-2">
|
||||
<span className="mt-1.5 size-1 shrink-0 rounded-full bg-primary" />
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
{/* Why hybrid */}
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-xl font-semibold tracking-tight">Why Hybrid?</h2>
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<div className="divide-y">
|
||||
{tradeoffs.map(({ concern, solution }) => (
|
||||
<div
|
||||
key={concern}
|
||||
className="flex flex-col gap-1 py-3 first:pt-0 last:pb-0 sm:flex-row sm:items-center sm:gap-4"
|
||||
>
|
||||
<span className="min-w-55 text-sm font-medium">
|
||||
{concern}
|
||||
</span>
|
||||
<span className="text-sm text-muted-foreground">
|
||||
{solution}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Communication */}
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-xl font-semibold tracking-tight">Communication</h2>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Next.js API routes call the Go service over HTTPS. The Go service URL
|
||||
is configured via{" "}
|
||||
<code className="rounded bg-muted px-1.5 py-0.5 font-mono text-xs">
|
||||
GO_DNS_API_URL
|
||||
</code>{" "}
|
||||
and requests are authenticated with a shared API key via{" "}
|
||||
<code className="rounded bg-muted px-1.5 py-0.5 font-mono text-xs">
|
||||
GO_DNS_API_KEY
|
||||
</code>
|
||||
.
|
||||
</p>
|
||||
<Card>
|
||||
<CardContent className="p-0">
|
||||
<pre className="overflow-x-auto bg-muted/50 p-4 font-mono text-sm text-foreground">
|
||||
Next.js API route → HTTPS → Go DNS API → UDP/TCP → DNS resolvers
|
||||
</pre>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Why Go over DoH */}
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-xl font-semibold tracking-tight">
|
||||
Why Go Over DoH?
|
||||
</h2>
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardDescription>
|
||||
VectorDNS uses a custom Go microservice for DNS resolution instead
|
||||
of DNS-over-HTTPS providers like Cloudflare's Tangerine.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ul className="space-y-2 text-sm text-muted-foreground">
|
||||
{goAdvantages.map((item) => (
|
||||
<li key={item} className="flex gap-2">
|
||||
<span className="mt-1.5 size-1 shrink-0 rounded-full bg-primary" />
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user