mirror of
https://github.com/DevVoxel/VectorDNS.git
synced 2026-02-27 09:57:39 +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:
412
app/docs/api/page.tsx
Normal file
412
app/docs/api/page.tsx
Normal file
@@ -0,0 +1,412 @@
|
||||
import type { Metadata } from "next";
|
||||
import { FileCode, ArrowRight, CheckCircle, XCircle } from "lucide-react";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "API Reference",
|
||||
};
|
||||
|
||||
function Method({ method }: { method: string }) {
|
||||
const colors: Record<string, string> = {
|
||||
GET: "bg-blue-500/10 text-blue-400 border-blue-500/20",
|
||||
POST: "bg-green-500/10 text-green-400 border-green-500/20",
|
||||
};
|
||||
return (
|
||||
<span
|
||||
className={`inline-flex items-center rounded border px-2 py-0.5 font-mono text-xs font-semibold ${colors[method] ?? "bg-muted text-muted-foreground"}`}
|
||||
>
|
||||
{method}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function CodeBlock({ code }: { code: string }) {
|
||||
return (
|
||||
<pre className="overflow-x-auto rounded-md border bg-muted/50 p-4 font-mono text-sm leading-relaxed">
|
||||
<code>{code.trim()}</code>
|
||||
</pre>
|
||||
);
|
||||
}
|
||||
|
||||
function StatusBadge({ code }: { code: number }) {
|
||||
const isOk = code < 400;
|
||||
return (
|
||||
<span
|
||||
className={`inline-flex items-center gap-1 rounded px-1.5 py-0.5 font-mono text-xs font-medium ${isOk ? "bg-green-500/10 text-green-400" : "bg-red-500/10 text-red-400"}`}
|
||||
>
|
||||
{isOk ? (
|
||||
<CheckCircle className="size-3" />
|
||||
) : (
|
||||
<XCircle className="size-3" />
|
||||
)}
|
||||
{code}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ApiReferencePage() {
|
||||
return (
|
||||
<div className="space-y-10">
|
||||
{/* Header */}
|
||||
<div>
|
||||
<div className="mb-3 flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<FileCode className="size-4" />
|
||||
<span>Go Server</span>
|
||||
<ArrowRight className="size-3" />
|
||||
<span>API Reference</span>
|
||||
</div>
|
||||
<h1 className="text-3xl font-bold tracking-tight">API Reference</h1>
|
||||
<p className="mt-2 text-muted-foreground">
|
||||
Complete reference for the VectorDNS Go server REST API.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Base URL & Auth */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-base">
|
||||
Base URL & Authentication
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div>
|
||||
<p className="mb-2 text-sm text-muted-foreground">Base URL</p>
|
||||
<CodeBlock code="https://<your-vps-host>/api/v1" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="mb-2 text-sm text-muted-foreground">
|
||||
All requests (except{" "}
|
||||
<span className="font-mono text-xs">/health</span>) require an API
|
||||
key header:
|
||||
</p>
|
||||
<CodeBlock code="X-API-Key: <your-shared-secret>" />
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Set{" "}
|
||||
<span className="font-mono text-xs bg-muted px-1 py-0.5 rounded">
|
||||
API_KEY
|
||||
</span>{" "}
|
||||
in your server environment to enable authentication. If left empty,
|
||||
auth is disabled (not recommended for production).
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Endpoints */}
|
||||
<div className="space-y-6">
|
||||
<h2 className="text-xl font-semibold tracking-tight">Endpoints</h2>
|
||||
|
||||
{/* DNS Lookup */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-3">
|
||||
<Method method="POST" />
|
||||
<code className="font-mono text-sm font-semibold">
|
||||
/dns/lookup
|
||||
</code>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Resolve DNS records for a domain. Query one or more record types
|
||||
in a single request.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div>
|
||||
<p className="mb-2 text-sm font-medium">Request</p>
|
||||
<CodeBlock
|
||||
code={`{
|
||||
"domain": "example.com",
|
||||
"types": ["A", "AAAA", "MX", "TXT", "NS", "CNAME", "SOA", "CAA", "SRV"],
|
||||
"nameserver": "8.8.8.8"
|
||||
}`}
|
||||
/>
|
||||
<ul className="mt-3 space-y-1 text-sm text-muted-foreground">
|
||||
<li>
|
||||
<span className="font-mono text-xs text-foreground">
|
||||
domain
|
||||
</span>{" "}
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
required
|
||||
</Badge>{" "}
|
||||
— The domain to query.
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-mono text-xs text-foreground">
|
||||
types
|
||||
</span>{" "}
|
||||
<Badge variant="outline" className="text-xs">
|
||||
optional
|
||||
</Badge>{" "}
|
||||
— Record types to query. Defaults to all 9 supported types if
|
||||
omitted.
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-mono text-xs text-foreground">
|
||||
nameserver
|
||||
</span>{" "}
|
||||
<Badge variant="outline" className="text-xs">
|
||||
optional
|
||||
</Badge>{" "}
|
||||
— Specific nameserver to query. Defaults to system resolver.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<Separator />
|
||||
<div>
|
||||
<div className="mb-2 flex items-center gap-2">
|
||||
<p className="text-sm font-medium">Response</p>
|
||||
<StatusBadge code={200} />
|
||||
</div>
|
||||
<CodeBlock
|
||||
code={`{
|
||||
"domain": "example.com",
|
||||
"nameserver": "8.8.8.8",
|
||||
"records": {
|
||||
"A": [{ "value": "93.184.216.34", "ttl": 300 }],
|
||||
"MX": [{ "value": "mail.example.com", "priority": 10, "ttl": 3600 }]
|
||||
},
|
||||
"query_time_ms": 12
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* DNS Propagation */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-3">
|
||||
<Method method="POST" />
|
||||
<code className="font-mono text-sm font-semibold">
|
||||
/dns/propagation
|
||||
</code>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Check DNS propagation across multiple public resolvers. Queries
|
||||
resolvers in parallel and compares results.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div>
|
||||
<p className="mb-2 text-sm font-medium">Request</p>
|
||||
<CodeBlock
|
||||
code={`{
|
||||
"domain": "example.com",
|
||||
"type": "A",
|
||||
"resolvers": ["8.8.8.8", "1.1.1.1", "9.9.9.9"]
|
||||
}`}
|
||||
/>
|
||||
<ul className="mt-3 space-y-1 text-sm text-muted-foreground">
|
||||
<li>
|
||||
<span className="font-mono text-xs text-foreground">
|
||||
domain
|
||||
</span>{" "}
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
required
|
||||
</Badge>{" "}
|
||||
— The domain to check.
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-mono text-xs text-foreground">
|
||||
type
|
||||
</span>{" "}
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
required
|
||||
</Badge>{" "}
|
||||
— The record type to check (e.g.{" "}
|
||||
<span className="font-mono text-xs">A</span>,{" "}
|
||||
<span className="font-mono text-xs">MX</span>).
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-mono text-xs text-foreground">
|
||||
resolvers
|
||||
</span>{" "}
|
||||
<Badge variant="outline" className="text-xs">
|
||||
optional
|
||||
</Badge>{" "}
|
||||
— List of resolver IPs. Defaults to a built-in list of public
|
||||
resolvers.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<Separator />
|
||||
<div>
|
||||
<div className="mb-2 flex items-center gap-2">
|
||||
<p className="text-sm font-medium">Response</p>
|
||||
<StatusBadge code={200} />
|
||||
</div>
|
||||
<CodeBlock
|
||||
code={`{
|
||||
"domain": "example.com",
|
||||
"type": "A",
|
||||
"results": [
|
||||
{ "resolver": "8.8.8.8", "values": ["93.184.216.34"], "ttl": 300 },
|
||||
{ "resolver": "1.1.1.1", "values": ["93.184.216.34"], "ttl": 280 },
|
||||
{ "resolver": "9.9.9.9", "values": ["93.184.216.34"], "ttl": 295 }
|
||||
],
|
||||
"consistent": true
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* DNSSEC Validate */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-3">
|
||||
<Method method="POST" />
|
||||
<code className="font-mono text-sm font-semibold">
|
||||
/dns/validate
|
||||
</code>
|
||||
</div>
|
||||
<CardDescription>
|
||||
DNSSEC validation for a domain. Checks the AD flag and verifies
|
||||
the signature chain.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div>
|
||||
<p className="mb-2 text-sm font-medium">Request</p>
|
||||
<CodeBlock
|
||||
code={`{
|
||||
"domain": "example.com"
|
||||
}`}
|
||||
/>
|
||||
<ul className="mt-3 space-y-1 text-sm text-muted-foreground">
|
||||
<li>
|
||||
<span className="font-mono text-xs text-foreground">
|
||||
domain
|
||||
</span>{" "}
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
required
|
||||
</Badge>{" "}
|
||||
— The domain to validate.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<Separator />
|
||||
<div>
|
||||
<div className="mb-2 flex items-center gap-2">
|
||||
<p className="text-sm font-medium">Response</p>
|
||||
<StatusBadge code={200} />
|
||||
</div>
|
||||
<CodeBlock
|
||||
code={`{
|
||||
"domain": "example.com",
|
||||
"dnssec": true,
|
||||
"chain_valid": true,
|
||||
"details": "RRSIG verified for A record"
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Health */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-3">
|
||||
<Method method="GET" />
|
||||
<code className="font-mono text-sm font-semibold">/health</code>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Health check endpoint. No authentication required. Use this for
|
||||
uptime monitoring.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div>
|
||||
<div className="mb-2 flex items-center gap-2">
|
||||
<p className="text-sm font-medium">Response</p>
|
||||
<StatusBadge code={200} />
|
||||
</div>
|
||||
<CodeBlock
|
||||
code={`{
|
||||
"status": "ok",
|
||||
"version": "0.1.0"
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Errors */}
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-xl font-semibold tracking-tight">
|
||||
Error Responses
|
||||
</h2>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
All errors return a consistent JSON body:
|
||||
</p>
|
||||
<CodeBlock
|
||||
code={`{
|
||||
"error": "invalid domain",
|
||||
"code": "INVALID_DOMAIN"
|
||||
}`}
|
||||
/>
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr className="border-b text-left text-muted-foreground">
|
||||
<th className="pb-2 pr-4 font-medium">Status</th>
|
||||
<th className="pb-2 pr-4 font-medium">Code</th>
|
||||
<th className="pb-2 font-medium">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y">
|
||||
{[
|
||||
{
|
||||
status: 400,
|
||||
code: "INVALID_DOMAIN",
|
||||
desc: "Malformed or missing domain",
|
||||
},
|
||||
{
|
||||
status: 400,
|
||||
code: "INVALID_TYPE",
|
||||
desc: "Unsupported record type",
|
||||
},
|
||||
{
|
||||
status: 401,
|
||||
code: "UNAUTHORIZED",
|
||||
desc: "Missing or invalid API key",
|
||||
},
|
||||
{
|
||||
status: 500,
|
||||
code: "DNS_ERROR",
|
||||
desc: "Upstream DNS query failed",
|
||||
},
|
||||
{
|
||||
status: 500,
|
||||
code: "INTERNAL",
|
||||
desc: "Unexpected server error",
|
||||
},
|
||||
].map((row) => (
|
||||
<tr key={row.code}>
|
||||
<td className="py-2 pr-4">
|
||||
<StatusBadge code={row.status} />
|
||||
</td>
|
||||
<td className="py-2 pr-4">
|
||||
<code className="font-mono text-xs">{row.code}</code>
|
||||
</td>
|
||||
<td className="py-2 text-muted-foreground">{row.desc}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user