Add architecture docs and Go microservice to tech stack

This commit is contained in:
Aiden Smith
2026-02-24 13:47:17 -05:00
parent 9a80accaf9
commit f49bdb7099
3 changed files with 219 additions and 1 deletions

135
docs/api-spec.md Normal file
View File

@@ -0,0 +1,135 @@
# Go DNS API Specification
Base URL: `https://<vps-host>/api/v1`
All requests require the header `X-API-Key: <shared-secret>`.
---
## Endpoints
### `POST /dns/lookup`
Resolve DNS records for a domain.
**Request:**
```json
{
"domain": "example.com",
"types": ["A", "AAAA", "MX", "TXT", "NS", "CNAME", "SOA", "CAA", "SRV"],
"nameserver": "8.8.8.8"
}
```
- `domain` (required): The domain to query.
- `types` (optional): Record types to query. Defaults to all supported types.
- `nameserver` (optional): Specific nameserver to query. Defaults to system resolver.
**Response (200):**
```json
{
"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
}
```
---
### `POST /dns/propagation`
Check DNS propagation across multiple resolvers.
**Request:**
```json
{
"domain": "example.com",
"type": "A",
"resolvers": ["8.8.8.8", "1.1.1.1", "9.9.9.9"]
}
```
- `resolvers` (optional): Defaults to a built-in list of public resolvers.
**Response (200):**
```json
{
"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
}
```
---
### `POST /dns/validate`
DNSSEC validation for a domain.
**Request:**
```json
{
"domain": "example.com"
}
```
**Response (200):**
```json
{
"domain": "example.com",
"dnssec": true,
"chain_valid": true,
"details": "RRSIG verified for A record"
}
```
---
### `GET /health`
Health check. No authentication required.
**Response (200):**
```json
{
"status": "ok",
"version": "0.1.0"
}
```
---
## Error Responses
All errors follow this format:
```json
{
"error": "invalid domain",
"code": "INVALID_DOMAIN"
}
```
| HTTP Status | Code | Description |
|---|---|---|
| 400 | `INVALID_DOMAIN` | Malformed or missing domain |
| 400 | `INVALID_TYPE` | Unsupported record type |
| 401 | `UNAUTHORIZED` | Missing or invalid API key |
| 500 | `DNS_ERROR` | Upstream DNS query failed |
| 500 | `INTERNAL` | Unexpected server error |

78
docs/architecture.md Normal file
View File

@@ -0,0 +1,78 @@
# VectorDNS Architecture
## Overview
VectorDNS uses a hybrid architecture: a Next.js frontend on Vercel and a Go DNS microservice on a VPS.
```
┌──────────────────────┐ ┌──────────────────────┐
│ Vercel (Frontend) │ │ VPS (DNS API) │
│ │ │ │
│ Next.js 16 │ HTTP │ Go microservice │
│ React 19 │◄──────►│ miekg/dns │
│ Supabase SDK │ │ │
│ Tailwind + shadcn │ │ - DNS resolution │
│ │ │ - DNSSEC validation │
│ Handles: │ │ - Propagation checks │
│ - UI/SSR │ │ - Monitoring cron │
│ - Auth (Supabase) │ │ - Change detection │
│ - WHOIS lookups │ │ │
│ - Static pages │ └───────────┬───────────┘
│ │ │
└──────────┬───────────┘ │ UDP/TCP
│ ▼
│ ┌───────────────────────┐
│ │ DNS Resolvers / │
▼ │ Authoritative NS │
┌──────────────────────┐ └───────────────────────┘
│ Supabase │
│ │
│ - Postgres DB │
│ - Auth │
│ - Row Level Security│
└──────────────────────┘
```
## Why Hybrid
| Concern | Solution |
|---|---|
| Frontend hosting, SSR, auth | Vercel (serverless, zero-ops) |
| DNS resolution, monitoring | Go on VPS (persistent process, no cold starts) |
| Database, auth state | Supabase (managed Postgres) |
## What Each Service Handles
### Next.js (Vercel)
- 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
### Go Microservice (VPS)
- 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)
## Communication
The Next.js API routes call the Go service over HTTPS. The Go service URL is configured via environment variable (`GO_DNS_API_URL`). Requests are authenticated with a shared API key (`GO_DNS_API_KEY`).
```
Next.js API route → HTTPS → Go DNS API → UDP/TCP → DNS resolvers
```
## Why Go Over DoH (Tangerine)
- 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