syncova-backup/SYNCOVA_DATABASE.md
Jerrit Fritzsche 610719c316
Some checks failed
CI / Backend (Go) (push) Failing after 3m7s
CI / Frontend (React/TypeScript) (push) Successful in 37s
CI / Sicherheitsprüfungen (push) Successful in 44s
Syncova Backups V1
Enterprise-Backup-, Recovery-, Verification-, Security- und
Monitoring-Plattform fuer Proxmox VE, Windows, Linux und Dateisysteme.

Der Leitsatz, der fast jede Entscheidung erklaert: Ein Backup gilt erst als
vertrauenswuerdig, wenn Integritaet geprueft und Wiederherstellbarkeit
nachgewiesen wurde. Deshalb steigt ein Wiederherstellungspunkt erst nach einem
tatsaechlich durchgefuehrten Restore-Test auf "recoverable", und Unbekanntes
geht in keine Bewertung als "gut" ein.

Umfang (Phasen 0-23):

- Repository Engine: inhaltsadressierte Bloecke, atomares Commit-Protokoll,
  Katalogaufbau allein aus den Manifesten — ohne Datenbank
- Backup Engine: inhaltsabhaengiges Chunking, Deduplizierung trotz
  Verschluesselung, zstd, AES-256-GCM, Streaming mit Gegendruck
- Agenten fuer Windows und Linux mit Auftragsabholung (Pull-Modell)
- Proxmox-Provider mit beiden Zugriffswegen auf die Sicherungsarchive
- Scheduler, Recovery Engine mit Pruefpunkt, Verification, Unveraenderlichkeit
- Weboberflaeche, Kennzahlen, Meldungen, Berichte, Security Center,
  Ransomware-Heuristik (meldet, handelt nie)
- Disaster Recovery, Haertung, Leistungsmessung, Chaos Testing
- Eingefrorene Vertraege fuer API, Migrationen, Backup-Format und Repository
- Auslieferungspaket fuer linux/amd64, linux/arm64 und windows/amd64

Nicht enthalten und als solches gekennzeichnet: Kapazitaetsprognose, Backup
Copy, Changed Block Tracking bei Proxmox, erweiterte Attribute und ACLs.

Gebaut, aber nie auf echter Hardware gefahren: der Windows-Dienst, die
systemd-Einheit und der verpflichtende Proxmox-Meilenstein — ob eine
wiederhergestellte VM startet, ist ungeprueft. Einzelheiten in CHANGELOG.md
und docs/release-candidate.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 09:10:54 +02:00

539 lines
9.8 KiB
Markdown

# Syncova Backups V1 — PostgreSQL Database Design
## 1. Database Rules
- PostgreSQL is the control-plane database.
- Backup payloads are never stored in PostgreSQL.
- UUIDs are preferred for public identifiers.
- All timestamps are UTC.
- Foreign keys are mandatory for relationships.
- Use soft deletion where audit/history requires it.
- Never store passwords or raw encryption keys.
- Every schema change uses a migration.
## 2. Core Tables
### users
```sql
id UUID PRIMARY KEY
username TEXT UNIQUE NOT NULL
email TEXT UNIQUE
password_hash TEXT
status TEXT NOT NULL
mfa_enabled BOOLEAN NOT NULL DEFAULT FALSE
created_at TIMESTAMPTZ NOT NULL
updated_at TIMESTAMPTZ NOT NULL
last_login_at TIMESTAMPTZ
```
### user_mfa_methods
```sql
id UUID PRIMARY KEY
user_id UUID REFERENCES users(id)
type TEXT NOT NULL
secret_ciphertext BYTEA
enabled BOOLEAN NOT NULL
created_at TIMESTAMPTZ NOT NULL
```
### roles
```sql
id UUID PRIMARY KEY
name TEXT UNIQUE NOT NULL
description TEXT
```
### permissions
```sql
id UUID PRIMARY KEY
name TEXT UNIQUE NOT NULL
description TEXT
```
### role_permissions
```sql
role_id UUID REFERENCES roles(id)
permission_id UUID REFERENCES permissions(id)
PRIMARY KEY(role_id, permission_id)
```
### user_roles
```sql
user_id UUID REFERENCES users(id)
role_id UUID REFERENCES roles(id)
PRIMARY KEY(user_id, role_id)
```
## 3. Agents
### agents
```sql
id UUID PRIMARY KEY
name TEXT NOT NULL
hostname TEXT
platform TEXT NOT NULL
version TEXT
status TEXT NOT NULL
last_heartbeat_at TIMESTAMPTZ
registered_at TIMESTAMPTZ NOT NULL
created_at TIMESTAMPTZ NOT NULL
updated_at TIMESTAMPTZ NOT NULL
```
### agent_certificates
```sql
id UUID PRIMARY KEY
agent_id UUID REFERENCES agents(id)
fingerprint TEXT UNIQUE NOT NULL
not_before TIMESTAMPTZ
not_after TIMESTAMPTZ
status TEXT NOT NULL
created_at TIMESTAMPTZ NOT NULL
```
## 4. Proxmox
### proxmox_clusters
```sql
id UUID PRIMARY KEY
name TEXT NOT NULL
api_endpoint TEXT NOT NULL
credential_ref TEXT NOT NULL
status TEXT NOT NULL
created_at TIMESTAMPTZ NOT NULL
updated_at TIMESTAMPTZ NOT NULL
```
### proxmox_hosts
```sql
id UUID PRIMARY KEY
cluster_id UUID REFERENCES proxmox_clusters(id)
node_name TEXT NOT NULL
status TEXT NOT NULL
last_seen_at TIMESTAMPTZ
created_at TIMESTAMPTZ NOT NULL
```
### virtual_machines
```sql
id UUID PRIMARY KEY
cluster_id UUID REFERENCES proxmox_clusters(id)
host_id UUID REFERENCES proxmox_hosts(id)
provider_vm_id TEXT NOT NULL
name TEXT NOT NULL
status TEXT
cpu_count INTEGER
memory_bytes BIGINT
config_json JSONB
last_discovered_at TIMESTAMPTZ
created_at TIMESTAMPTZ NOT NULL
updated_at TIMESTAMPTZ NOT NULL
UNIQUE(cluster_id, provider_vm_id)
```
## 5. Repositories
### repositories
```sql
id UUID PRIMARY KEY
name TEXT UNIQUE NOT NULL
type TEXT NOT NULL
endpoint TEXT NOT NULL
status TEXT NOT NULL
capacity_bytes BIGINT
used_bytes BIGINT
free_bytes BIGINT
immutable BOOLEAN NOT NULL DEFAULT FALSE
encryption_required BOOLEAN NOT NULL DEFAULT TRUE
created_at TIMESTAMPTZ NOT NULL
updated_at TIMESTAMPTZ NOT NULL
```
### repository_health
```sql
id UUID PRIMARY KEY
repository_id UUID REFERENCES repositories(id)
health_status TEXT NOT NULL
latency_ms DOUBLE PRECISION
error_count BIGINT DEFAULT 0
checked_at TIMESTAMPTZ NOT NULL
details JSONB
```
## 6. Backup Jobs
### backup_jobs
```sql
id UUID PRIMARY KEY
name TEXT UNIQUE NOT NULL
description TEXT
status TEXT NOT NULL
priority TEXT NOT NULL
schedule_type TEXT NOT NULL
schedule_config JSONB NOT NULL
retention_policy_id UUID
repository_id UUID REFERENCES repositories(id)
encryption_policy_id UUID
verification_policy_id UUID
notification_policy_id UUID
rpo_seconds BIGINT
rto_seconds BIGINT
bandwidth_limit_bps BIGINT
max_concurrency INTEGER
created_by UUID REFERENCES users(id)
created_at TIMESTAMPTZ NOT NULL
updated_at TIMESTAMPTZ NOT NULL
```
### backup_job_sources
```sql
id UUID PRIMARY KEY
job_id UUID REFERENCES backup_jobs(id)
source_type TEXT NOT NULL
source_id UUID
include_patterns JSONB
exclude_patterns JSONB
created_at TIMESTAMPTZ NOT NULL
```
## 7. Backup Runs
### backup_job_runs
```sql
id UUID PRIMARY KEY
job_id UUID REFERENCES backup_jobs(id)
status TEXT NOT NULL
started_at TIMESTAMPTZ
completed_at TIMESTAMPTZ
bytes_processed BIGINT DEFAULT 0
bytes_written BIGINT DEFAULT 0
bytes_transferred BIGINT DEFAULT 0
throughput_bps BIGINT
error_code TEXT
error_message TEXT
correlation_id UUID NOT NULL
created_at TIMESTAMPTZ NOT NULL
```
## 8. Backups and Chains
### backup_chains
```sql
id UUID PRIMARY KEY
source_id UUID NOT NULL
status TEXT NOT NULL
created_at TIMESTAMPTZ NOT NULL
```
### backups
```sql
id UUID PRIMARY KEY
job_run_id UUID REFERENCES backup_job_runs(id)
chain_id UUID REFERENCES backup_chains(id)
repository_id UUID REFERENCES repositories(id)
parent_backup_id UUID REFERENCES backups(id)
backup_type TEXT NOT NULL
consistency_level TEXT
status TEXT NOT NULL
manifest_ref TEXT NOT NULL
logical_bytes BIGINT
unique_bytes BIGINT
compressed_bytes BIGINT
encrypted_bytes BIGINT
started_at TIMESTAMPTZ
completed_at TIMESTAMPTZ
integrity_status TEXT
verified_at TIMESTAMPTZ
immutable_until TIMESTAMPTZ
created_at TIMESTAMPTZ NOT NULL
```
## 9. Chunks
The database stores references/index information, not chunk payloads.
### chunks
```sql
id UUID PRIMARY KEY
repository_id UUID REFERENCES repositories(id)
content_hash TEXT NOT NULL
size_bytes BIGINT NOT NULL
compressed_size_bytes BIGINT
encryption_version TEXT
storage_ref TEXT NOT NULL
created_at TIMESTAMPTZ NOT NULL
UNIQUE(repository_id, content_hash)
```
### chunk_references
```sql
backup_id UUID REFERENCES backups(id)
chunk_id UUID REFERENCES chunks(id)
sequence_no BIGINT NOT NULL
logical_offset BIGINT
length_bytes BIGINT
PRIMARY KEY(backup_id, sequence_no)
```
## 10. Restore
### restore_jobs
```sql
id UUID PRIMARY KEY
backup_id UUID REFERENCES backups(id)
source_type TEXT NOT NULL
target_type TEXT NOT NULL
target_ref TEXT
status TEXT NOT NULL
started_at TIMESTAMPTZ
completed_at TIMESTAMPTZ
bytes_restored BIGINT
error_code TEXT
error_message TEXT
created_by UUID REFERENCES users(id)
created_at TIMESTAMPTZ NOT NULL
```
### restore_sessions
```sql
id UUID PRIMARY KEY
restore_job_id UUID REFERENCES restore_jobs(id)
state TEXT NOT NULL
checkpoint JSONB
created_at TIMESTAMPTZ NOT NULL
updated_at TIMESTAMPTZ NOT NULL
```
## 11. Verification
### verification_jobs
```sql
id UUID PRIMARY KEY
backup_id UUID REFERENCES backups(id)
type TEXT NOT NULL
status TEXT NOT NULL
started_at TIMESTAMPTZ
completed_at TIMESTAMPTZ
created_at TIMESTAMPTZ NOT NULL
```
### verification_results
```sql
id UUID PRIMARY KEY
verification_job_id UUID REFERENCES verification_jobs(id)
check_name TEXT NOT NULL
status TEXT NOT NULL
details JSONB
created_at TIMESTAMPTZ NOT NULL
```
## 12. Alerts and Events
### alert_rules
```sql
id UUID PRIMARY KEY
name TEXT UNIQUE NOT NULL
enabled BOOLEAN NOT NULL DEFAULT TRUE
severity TEXT NOT NULL
condition JSONB NOT NULL
actions JSONB NOT NULL
created_at TIMESTAMPTZ NOT NULL
updated_at TIMESTAMPTZ NOT NULL
```
### alerts
```sql
id UUID PRIMARY KEY
rule_id UUID REFERENCES alert_rules(id)
severity TEXT NOT NULL
status TEXT NOT NULL
title TEXT NOT NULL
message TEXT NOT NULL
entity_type TEXT
entity_id UUID
created_at TIMESTAMPTZ NOT NULL
acknowledged_at TIMESTAMPTZ
resolved_at TIMESTAMPTZ
```
### events
```sql
id UUID PRIMARY KEY
event_type TEXT NOT NULL
severity TEXT NOT NULL
entity_type TEXT
entity_id UUID
message TEXT NOT NULL
details JSONB
correlation_id UUID
created_at TIMESTAMPTZ NOT NULL
```
## 13. Audit
### audit_events
```sql
id UUID PRIMARY KEY
user_id UUID REFERENCES users(id)
action TEXT NOT NULL
entity_type TEXT
entity_id UUID
result TEXT NOT NULL
ip_address INET
user_agent TEXT
details JSONB
correlation_id UUID
created_at TIMESTAMPTZ NOT NULL
```
Audit data should be append-oriented.
## 14. Metrics
### metrics
```sql
id BIGSERIAL PRIMARY KEY
metric_name TEXT NOT NULL
entity_type TEXT
entity_id UUID
value DOUBLE PRECISION NOT NULL
unit TEXT
timestamp TIMESTAMPTZ NOT NULL
labels JSONB
```
Use indexes on:
```text
(metric_name, timestamp)
(entity_type, entity_id, timestamp)
```
For large installations, introduce time partitioning and rollups.
## 15. Policies
### retention_policies
```sql
id UUID PRIMARY KEY
name TEXT UNIQUE NOT NULL
rules JSONB NOT NULL
created_at TIMESTAMPTZ NOT NULL
updated_at TIMESTAMPTZ NOT NULL
```
### encryption_policies
```sql
id UUID PRIMARY KEY
name TEXT UNIQUE NOT NULL
algorithm TEXT NOT NULL
key_ref TEXT NOT NULL
rotation_policy JSONB
created_at TIMESTAMPTZ NOT NULL
updated_at TIMESTAMPTZ NOT NULL
```
### verification_policies
```sql
id UUID PRIMARY KEY
name TEXT UNIQUE NOT NULL
rules JSONB NOT NULL
created_at TIMESTAMPTZ NOT NULL
updated_at TIMESTAMPTZ NOT NULL
```
### notification_policies
```sql
id UUID PRIMARY KEY
name TEXT UNIQUE NOT NULL
channels JSONB NOT NULL
rules JSONB NOT NULL
created_at TIMESTAMPTZ NOT NULL
updated_at TIMESTAMPTZ NOT NULL
```
## 16. Certificates and Configuration
### certificates
```sql
id UUID PRIMARY KEY
name TEXT UNIQUE NOT NULL
type TEXT NOT NULL
fingerprint TEXT UNIQUE NOT NULL
not_before TIMESTAMPTZ
not_after TIMESTAMPTZ
status TEXT NOT NULL
secret_ref TEXT
created_at TIMESTAMPTZ NOT NULL
```
### system_settings
```sql
key TEXT PRIMARY KEY
value_json JSONB NOT NULL
updated_at TIMESTAMPTZ NOT NULL
updated_by UUID REFERENCES users(id)
```
## 17. Recommended Indexes
Create indexes for:
- backup_jobs(status)
- backup_job_runs(job_id, started_at DESC)
- backups(repository_id, completed_at DESC)
- backups(chain_id, completed_at DESC)
- backups(parent_backup_id)
- virtual_machines(cluster_id)
- agents(status)
- alerts(status, severity, created_at DESC)
- events(created_at DESC)
- audit_events(created_at DESC)
- metrics(metric_name, timestamp DESC)
## 18. Migration Strategy
Use a migration tool such as:
- golang-migrate
- Atlas
Every schema change must be versioned.
Production startup must never silently mutate the schema.