280 lines
9.5 KiB
Markdown
280 lines
9.5 KiB
Markdown
# Database Configuration Schema Design
|
|
|
|
## Overview
|
|
This document outlines the database configuration schema additions for the C Nostr Relay startup config file system. The design follows the Ginxsom admin system approach with signed Nostr events and database storage.
|
|
|
|
## Schema Version Update
|
|
- Current Version: 2
|
|
- Target Version: 3
|
|
- Update: Add server configuration management tables
|
|
|
|
## Core Configuration Tables
|
|
|
|
### 1. `server_config` Table
|
|
|
|
```sql
|
|
-- Server configuration table - core configuration storage
|
|
CREATE TABLE server_config (
|
|
key TEXT PRIMARY KEY, -- Configuration key (unique identifier)
|
|
value TEXT NOT NULL, -- Configuration value (stored as string)
|
|
description TEXT, -- Human-readable description
|
|
config_type TEXT DEFAULT 'user' CHECK (config_type IN ('system', 'user', 'runtime')),
|
|
data_type TEXT DEFAULT 'string' CHECK (data_type IN ('string', 'integer', 'boolean', 'json')),
|
|
validation_rules TEXT, -- JSON validation rules (optional)
|
|
is_sensitive INTEGER DEFAULT 0, -- 1 if value should be masked in logs
|
|
requires_restart INTEGER DEFAULT 0, -- 1 if change requires server restart
|
|
created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
|
|
updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))
|
|
);
|
|
```
|
|
|
|
**Configuration Types:**
|
|
- `system`: Core system settings (admin keys, security)
|
|
- `user`: User-configurable settings (relay info, features)
|
|
- `runtime`: Dynamic runtime values (statistics, cache)
|
|
|
|
**Data Types:**
|
|
- `string`: Text values
|
|
- `integer`: Numeric values
|
|
- `boolean`: True/false values (stored as "true"/"false")
|
|
- `json`: JSON object/array values
|
|
|
|
### 2. `config_history` Table
|
|
|
|
```sql
|
|
-- Configuration change history table
|
|
CREATE TABLE config_history (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
config_key TEXT NOT NULL, -- Key that was changed
|
|
old_value TEXT, -- Previous value (NULL for new keys)
|
|
new_value TEXT NOT NULL, -- New value
|
|
changed_by TEXT DEFAULT 'system', -- Who made the change (system/admin/user)
|
|
change_reason TEXT, -- Optional reason for change
|
|
changed_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
|
|
FOREIGN KEY (config_key) REFERENCES server_config(key)
|
|
);
|
|
```
|
|
|
|
### 3. `config_validation_log` Table
|
|
|
|
```sql
|
|
-- Configuration validation errors log
|
|
CREATE TABLE config_validation_log (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
config_key TEXT NOT NULL,
|
|
attempted_value TEXT,
|
|
validation_error TEXT NOT NULL,
|
|
error_source TEXT DEFAULT 'validation', -- validation/parsing/constraint
|
|
attempted_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))
|
|
);
|
|
```
|
|
|
|
### 4. Configuration File Cache Table
|
|
|
|
```sql
|
|
-- Cache for file-based configuration events
|
|
CREATE TABLE config_file_cache (
|
|
file_path TEXT PRIMARY KEY, -- Full path to config file
|
|
file_hash TEXT NOT NULL, -- SHA256 hash of file content
|
|
event_id TEXT, -- Nostr event ID from file
|
|
event_pubkey TEXT, -- Admin pubkey that signed event
|
|
loaded_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
|
|
validation_status TEXT CHECK (validation_status IN ('valid', 'invalid', 'unverified')),
|
|
validation_error TEXT -- Error details if invalid
|
|
);
|
|
```
|
|
|
|
## Indexes and Performance
|
|
|
|
```sql
|
|
-- Performance indexes for configuration tables
|
|
CREATE INDEX idx_server_config_type ON server_config(config_type);
|
|
CREATE INDEX idx_server_config_updated ON server_config(updated_at DESC);
|
|
CREATE INDEX idx_config_history_key ON config_history(config_key);
|
|
CREATE INDEX idx_config_history_time ON config_history(changed_at DESC);
|
|
CREATE INDEX idx_config_validation_key ON config_validation_log(config_key);
|
|
CREATE INDEX idx_config_validation_time ON config_validation_log(attempted_at DESC);
|
|
```
|
|
|
|
## Triggers
|
|
|
|
### Update Timestamp Trigger
|
|
|
|
```sql
|
|
-- Trigger to update timestamp on configuration changes
|
|
CREATE TRIGGER update_config_timestamp
|
|
AFTER UPDATE ON server_config
|
|
BEGIN
|
|
UPDATE server_config SET updated_at = strftime('%s', 'now') WHERE key = NEW.key;
|
|
END;
|
|
```
|
|
|
|
### Configuration History Trigger
|
|
|
|
```sql
|
|
-- Trigger to log configuration changes to history
|
|
CREATE TRIGGER log_config_changes
|
|
AFTER UPDATE ON server_config
|
|
WHEN OLD.value != NEW.value
|
|
BEGIN
|
|
INSERT INTO config_history (config_key, old_value, new_value, changed_by, change_reason)
|
|
VALUES (NEW.key, OLD.value, NEW.value, 'system', 'configuration update');
|
|
END;
|
|
```
|
|
|
|
## Default Configuration Values
|
|
|
|
### Core System Settings
|
|
|
|
```sql
|
|
INSERT OR IGNORE INTO server_config (key, value, description, config_type, data_type, requires_restart) VALUES
|
|
-- Administrative settings
|
|
('admin_pubkey', '', 'Authorized admin public key (hex)', 'system', 'string', 1),
|
|
('admin_enabled', 'false', 'Enable admin interface', 'system', 'boolean', 1),
|
|
|
|
-- Server core settings
|
|
('relay_port', '8888', 'WebSocket server port', 'user', 'integer', 1),
|
|
('database_path', 'db/c_nostr_relay.db', 'SQLite database file path', 'user', 'string', 1),
|
|
('max_connections', '100', 'Maximum concurrent connections', 'user', 'integer', 1),
|
|
|
|
-- NIP-11 Relay Information
|
|
('relay_name', 'C Nostr Relay', 'Relay name for NIP-11', 'user', 'string', 0),
|
|
('relay_description', 'High-performance C Nostr relay with SQLite storage', 'Relay description', 'user', 'string', 0),
|
|
('relay_contact', '', 'Contact information', 'user', 'string', 0),
|
|
('relay_pubkey', '', 'Relay public key', 'user', 'string', 0),
|
|
('relay_software', 'https://git.laantungir.net/laantungir/c-relay.git', 'Software URL', 'user', 'string', 0),
|
|
('relay_version', '0.2.0', 'Software version', 'user', 'string', 0),
|
|
|
|
-- NIP-13 Proof of Work
|
|
('pow_enabled', 'true', 'Enable NIP-13 Proof of Work validation', 'user', 'boolean', 0),
|
|
('pow_min_difficulty', '0', 'Minimum PoW difficulty required', 'user', 'integer', 0),
|
|
('pow_mode', 'basic', 'PoW validation mode (basic/full/strict)', 'user', 'string', 0),
|
|
|
|
-- NIP-40 Expiration Timestamp
|
|
('expiration_enabled', 'true', 'Enable NIP-40 expiration handling', 'user', 'boolean', 0),
|
|
('expiration_strict', 'true', 'Reject expired events on submission', 'user', 'boolean', 0),
|
|
('expiration_filter', 'true', 'Filter expired events from responses', 'user', 'boolean', 0),
|
|
('expiration_grace_period', '300', 'Grace period for clock skew (seconds)', 'user', 'integer', 0),
|
|
|
|
-- Subscription limits
|
|
('max_subscriptions_per_client', '20', 'Max subscriptions per client', 'user', 'integer', 0),
|
|
('max_total_subscriptions', '5000', 'Max total concurrent subscriptions', 'user', 'integer', 0),
|
|
('subscription_id_max_length', '64', 'Maximum subscription ID length', 'user', 'integer', 0),
|
|
|
|
-- Event processing limits
|
|
('max_event_tags', '100', 'Maximum tags per event', 'user', 'integer', 0),
|
|
('max_content_length', '8196', 'Maximum content length', 'user', 'integer', 0),
|
|
('max_message_length', '16384', 'Maximum message length', 'user', 'integer', 0),
|
|
|
|
-- Performance settings
|
|
('default_limit', '500', 'Default query limit', 'user', 'integer', 0),
|
|
('max_limit', '5000', 'Maximum query limit', 'user', 'integer', 0);
|
|
```
|
|
|
|
### Runtime Statistics
|
|
|
|
```sql
|
|
INSERT OR IGNORE INTO server_config (key, value, description, config_type, data_type) VALUES
|
|
-- Runtime statistics (updated by server)
|
|
('server_start_time', '0', 'Server startup timestamp', 'runtime', 'integer'),
|
|
('total_events_processed', '0', 'Total events processed', 'runtime', 'integer'),
|
|
('total_subscriptions_created', '0', 'Total subscriptions created', 'runtime', 'integer'),
|
|
('current_connections', '0', 'Current active connections', 'runtime', 'integer'),
|
|
('database_size_bytes', '0', 'Database file size in bytes', 'runtime', 'integer');
|
|
```
|
|
|
|
## Configuration Views
|
|
|
|
### Active Configuration View
|
|
|
|
```sql
|
|
CREATE VIEW active_config AS
|
|
SELECT
|
|
key,
|
|
value,
|
|
description,
|
|
config_type,
|
|
data_type,
|
|
requires_restart,
|
|
updated_at
|
|
FROM server_config
|
|
WHERE config_type IN ('system', 'user')
|
|
ORDER BY config_type, key;
|
|
```
|
|
|
|
### Runtime Statistics View
|
|
|
|
```sql
|
|
CREATE VIEW runtime_stats AS
|
|
SELECT
|
|
key,
|
|
value,
|
|
description,
|
|
updated_at
|
|
FROM server_config
|
|
WHERE config_type = 'runtime'
|
|
ORDER BY key;
|
|
```
|
|
|
|
### Configuration Change Summary
|
|
|
|
```sql
|
|
CREATE VIEW recent_config_changes AS
|
|
SELECT
|
|
ch.config_key,
|
|
sc.description,
|
|
ch.old_value,
|
|
ch.new_value,
|
|
ch.changed_by,
|
|
ch.change_reason,
|
|
ch.changed_at
|
|
FROM config_history ch
|
|
JOIN server_config sc ON ch.config_key = sc.key
|
|
ORDER BY ch.changed_at DESC
|
|
LIMIT 50;
|
|
```
|
|
|
|
## Validation Rules Format
|
|
|
|
Configuration validation rules are stored as JSON strings in the `validation_rules` column:
|
|
|
|
```json
|
|
{
|
|
"type": "integer",
|
|
"min": 1,
|
|
"max": 65535,
|
|
"required": true
|
|
}
|
|
```
|
|
|
|
```json
|
|
{
|
|
"type": "string",
|
|
"pattern": "^[0-9a-fA-F]{64}$",
|
|
"required": false,
|
|
"description": "64-character hex string"
|
|
}
|
|
```
|
|
|
|
```json
|
|
{
|
|
"type": "boolean",
|
|
"required": true
|
|
}
|
|
```
|
|
|
|
## Migration Strategy
|
|
|
|
1. **Phase 1**: Add configuration tables to existing schema
|
|
2. **Phase 2**: Populate with current hardcoded values
|
|
3. **Phase 3**: Update application code to read from database
|
|
4. **Phase 4**: Add file-based configuration loading
|
|
5. **Phase 5**: Remove hardcoded defaults and environment variable fallbacks
|
|
|
|
## Integration Points
|
|
|
|
- **Startup**: Load configuration from file → database → apply to application
|
|
- **Runtime**: Read configuration values from database cache
|
|
- **Updates**: Write changes to database → optionally update file
|
|
- **Validation**: Validate all configuration changes before applying
|
|
- **History**: Track all configuration changes for audit purposes |