# Database Naming Design (c-relay Pattern)

## Overview

Following c-relay's architecture, ginxsom will use pubkey-based database naming to ensure database-key consistency and prevent mismatched configurations.

## Database Naming Convention

Database files are named after the blossom server's public key:
```
db/<blossom_pubkey>.db
```

Example:
```
db/52e366edfa4e9cc6a6d4653828e51ccf828a2f5a05227d7a768f33b5a198681a.db
```

## Startup Scenarios

### Scenario 1: No Arguments (Fresh Start)
```bash
./ginxsom-fcgi
```

**Behavior:**
1. Generate new server keypair
2. Create database file: `db/<new_pubkey>.db`
3. Store keys in the new database
4. Start server

**Result:** New instance with fresh keys and database

---

### Scenario 2: Database File Specified
```bash
./ginxsom-fcgi --db-path db/52e366ed...198681a.db
```

**Behavior:**
1. Open specified database
2. Load blossom_seckey from database
3. Verify pubkey matches database filename
4. Load admin_pubkey if present
5. Start server

**Validation:**
- Database MUST exist
- Database MUST contain blossom_seckey
- Derived pubkey MUST match filename

**Error Cases:**
- Database doesn't exist → Error: "Database file not found"
- Database missing blossom_seckey → Error: "Invalid database: missing server keys"
- Pubkey mismatch → Error: "Database pubkey mismatch: expected X, got Y"

---

### Scenario 3: Keys Specified (New Instance with Specific Keys)
```bash
./ginxsom-fcgi --server-privkey c4e0d2ed...309c48f1 --admin-pubkey 8ff74724...5eedde0e
```

**Behavior:**
1. Validate provided server private key
2. Derive server public key
3. Create database file: `db/<derived_pubkey>.db`
4. Store both keys in new database
5. Start server

**Validation:**
- server-privkey MUST be valid 64-char hex
- Derived database file MUST NOT already exist (prevents overwriting)

**Error Cases:**
- Invalid privkey format → Error: "Invalid server private key format"
- Database already exists → Error: "Database already exists for this pubkey"

---

### Scenario 4: Test Mode
```bash
./ginxsom-fcgi --test-keys
```

**Behavior:**
1. Load keys from `.test_keys` file
2. Derive server public key from SERVER_PRIVKEY
3. Create/overwrite database: `db/<test_pubkey>.db`
4. Store test keys in database
5. Start server

**Special Handling:**
- Test mode ALWAYS overwrites existing database (for clean testing)
- Database name derived from test SERVER_PRIVKEY

---

### Scenario 5: Database + Keys Specified (Validation Mode)
```bash
./ginxsom-fcgi --db-path db/52e366ed...198681a.db --server-privkey c4e0d2ed...309c48f1
```

**Behavior:**
1. Open specified database
2. Load blossom_seckey from database
3. Compare with provided --server-privkey
4. If match: continue normally
5. If mismatch: ERROR and exit

**Purpose:** Validation/verification that correct keys are being used

**Error Cases:**
- Key mismatch → Error: "Server private key doesn't match database"

---

## Command Line Options

### Updated Options

```
--db-path PATH          Database file path (must match pubkey if keys exist)
--storage-dir DIR       Storage directory for files (default: blobs)
--admin-pubkey KEY      Admin public key (only used when creating new database)
--server-privkey KEY    Server private key (creates new DB or validates existing)
--test-keys             Use test keys from .test_keys file
--generate-keys         Generate new keypair and create database (deprecated - default behavior)
--help, -h              Show this help message
```

### Removed Options

- `--generate-keys` - No longer needed, this is default behavior when no args provided

---

## Database Directory Structure

```
db/
├── 52e366edfa4e9cc6a6d4653828e51ccf828a2f5a05227d7a768f33b5a198681a.db  # Test instance
├── a1b2c3d4e5f6...xyz.db  # Production instance 1
├── f9e8d7c6b5a4...abc.db  # Production instance 2
└── schema.sql             # Schema template
```

Each database is completely independent and tied to its keypair.

---

## Implementation Logic Flow

```
START
  │
  ├─ Parse command line arguments
  │
  ├─ Initialize crypto system
  │
  ├─ Determine mode:
  │   │
  │   ├─ Test mode (--test-keys)?
  │   │   ├─ Load keys from .test_keys
  │   │   ├─ Derive pubkey
  │   │   ├─ Set db_path = db/<pubkey>.db
  │   │   └─ Create/overwrite database
  │   │
  │   ├─ Keys provided (--server-privkey)?
  │   │   ├─ Validate privkey format
  │   │   ├─ Derive pubkey
  │   │   ├─ Set db_path = db/<pubkey>.db
  │   │   │
  │   │   ├─ Database specified (--db-path)?
  │   │   │   ├─ YES: Validate keys match database
  │   │   │   └─ NO: Create new database
  │   │   │
  │   │   └─ Store keys in database
  │   │
  │   ├─ Database specified (--db-path)?
  │   │   ├─ Open database
  │   │   ├─ Load blossom_seckey
  │   │   ├─ Derive pubkey
  │   │   ├─ Validate pubkey matches filename
  │   │   └─ Load admin_pubkey
  │   │
  │   └─ No arguments (fresh start)?
  │       ├─ Generate new keypair
  │       ├─ Set db_path = db/<new_pubkey>.db
  │       └─ Create new database with keys
  │
  ├─ Initialize database schema (if new)
  │
  ├─ Load/validate all keys
  │
  └─ Start FastCGI server
```

---

## Migration Path

### For Existing Installations

1. **Backup current database:**
   ```bash
   cp db/ginxsom.db db/ginxsom.db.backup
   ```

2. **Extract current pubkey:**
   ```bash
   PUBKEY=$(sqlite3 db/ginxsom.db "SELECT value FROM config WHERE key='blossom_pubkey'")
   ```

3. **Rename database:**
   ```bash
   mv db/ginxsom.db db/${PUBKEY}.db
   ```

4. **Update restart-all.sh:**
   - Remove hardcoded `db/ginxsom.db` references
   - Let application determine database name from keys

---

## Benefits

1. **Database-Key Consistency:** Impossible to use wrong database with wrong keys
2. **Multiple Instances:** Can run multiple independent instances with different keys
3. **Clear Identity:** Database filename immediately identifies the server
4. **Test Isolation:** Test databases are clearly separate from production
5. **No Accidental Overwrites:** Each keypair has its own database
6. **Follows c-relay Pattern:** Proven architecture from production relay software

---

## Error Messages

### Clear, Actionable Errors

```
ERROR: Database file not found: db/52e366ed...198681a.db
  → Specify a different database or let the application create a new one

ERROR: Invalid database: missing server keys
  → Database is corrupted or not a valid ginxsom database

ERROR: Database pubkey mismatch
  Expected: 52e366edfa4e9cc6a6d4653828e51ccf828a2f5a05227d7a768f33b5a198681a
  Got:      a1b2c3d4e5f6789...
  → Database filename doesn't match the keys stored inside

ERROR: Server private key doesn't match database
  → The --server-privkey you provided doesn't match the database keys

ERROR: Database already exists for this pubkey: db/52e366ed...198681a.db
  → Use --db-path to open existing database or use different keys
```

---

## Testing Strategy

### Test Cases

1. **Fresh start (no args)** → Creates new database with generated keys
2. **Specify database** → Opens and validates existing database
3. **Specify keys** → Creates new database with those keys
4. **Test mode** → Uses test keys and creates test database
5. **Database + matching keys** → Validates and continues
6. **Database + mismatched keys** → Errors appropriately
7. **Invalid database path** → Clear error message
8. **Corrupted database** → Detects and reports

### Test Script

```bash
#!/bin/bash
# Test database naming system

# Test 1: Fresh start
./ginxsom-fcgi --generate-keys
# Should create db/<new_pubkey>.db

# Test 2: Test mode
./ginxsom-fcgi --test-keys
# Should create db/52e366ed...198681a.db

# Test 3: Specify keys
./ginxsom-fcgi --server-privkey abc123...
# Should create db/<derived_pubkey>.db

# Test 4: Open existing
./ginxsom-fcgi --db-path db/52e366ed...198681a.db
# Should open and validate

# Test 5: Mismatch error
./ginxsom-fcgi --db-path db/52e366ed...198681a.db --server-privkey wrong_key
# Should error with clear message