# Admin Guide

Complete guide for administrators using Ackify to manage documents, expected signers, and email reminders.

## Table of Contents

- [Getting Admin Access](#getting-admin-access)
- [Admin Dashboard](#admin-dashboard)
- [Document Management](#document-management)
- [Expected Signers](#expected-signers)
- [Email Reminders](#email-reminders)
- [Monitoring & Statistics](#monitoring--statistics)
- [Best Practices](#best-practices)
- [Troubleshooting](#troubleshooting)

---

## Getting Admin Access

### Prerequisites

To access admin features, your email must be configured in the `ACKIFY_ADMIN_EMAILS` environment variable.

```bash
# In .env file
ACKIFY_ADMIN_EMAILS=admin@company.com,manager@company.com
```

**After adding your email:**
1. Restart Ackify: `docker compose restart ackify-ce`
2. Log out and log in again
3. You should now see "Admin" link in the navigation

### Verify Admin Access

Visit `/admin` - if you see the admin dashboard, you have admin access.

---

## Admin Dashboard

**URL**: `/admin`

The admin dashboard provides:
- **Total Documents**: Number of documents in the system
- **Expected Readers**: Total number of expected signers across all documents
- **Active Documents**: Documents that are not soft-deleted
- **Document List**: Paginated list (20 per page) with search

### Dashboard Features

#### Quick Stats
Three KPI cards at the top:
- Total documents count
- Total expected readers/signers
- Active documents (non-deleted)

#### Document Search
- Search by title, document ID, or URL
- Real-time filtering

#### Document List
**Desktop view** - Table with columns:
- Document ID
- Title
- URL
- Created date
- Creator
- Actions (View details)

**Mobile view** - Card layout with:
- Document ID and title
- Creation info
- Tap to view details

#### Pagination
- 20 documents per page
- Previous/Next buttons
- Current page indicator

---

## Document Management

### Creating a Document

**From Admin Dashboard:**
1. Click "Create New Document" button
2. Fill in the form:
   - **Reference** (required): URL, file path, or custom ID
   - **Title** (optional): Auto-generated from URL if empty
   - **Description** (optional): Additional context
3. Click "Create Document"

**Automatic Features:**
- **Unique ID Generation**: Collision-resistant base36 doc_id
- **Title Extraction**: Auto-extracts from URL if not provided
- **Checksum Calculation**: For remote URLs (if admin and file < 10MB)

**Example:**
```
Reference: https://docs.company.com/policy-2025.pdf
Title: Security Policy 2025 (auto-extracted or manual)
Description: Annual security compliance policy
```

**Result:**
- doc_id: `k7m2n4p8` (auto-generated)
- Checksum: Auto-calculated SHA-256 (if URL is accessible)

### Viewing Document Details

**URL**: `/admin/docs/{docId}`

Provides comprehensive document information:

#### 1. **Metadata Section**
Edit document information:
- Title
- URL
- Description
- Checksum (SHA-256, SHA-512, or MD5)
- Checksum Algorithm

**To edit:**
1. Click "Edit Metadata" button
2. Modify fields
3. Click "Save Changes"
4. Confirmation modal for critical changes (checksum, algorithm)

#### 2. **Statistics Panel**
Real-time signature tracking:
- **Expected**: Number of expected signers
- **Signed**: Number who have signed
- **Pending**: Not yet signed
- **Completion**: Percentage complete

#### 3. **Expected Signers Section**
Lists all expected signers with status:
- **Email**: Signer's email address
- **Status**: ✅ Signed or ⏳ Pending
- **Added**: Date when added to expected list
- **Days Since Added**: Time tracking
- **Last Reminder**: When last reminder was sent
- **Reminder Count**: Total reminders sent
- **Actions**: Remove signer button

**Color coding:**
- Green background: Signer has signed
- Default background: Pending signature

#### 4. **Unexpected Signatures**
Shows users who signed but weren't on expected list:
- User email
- Signed date
- Indicates organic/unexpected participation

#### 5. **Actions**
- **Send Reminders**: Email pending signers
- **Share Link**: Generate and copy signing link
- **Delete Document**: Soft delete (preserves signature history)

### Updating Document Metadata

**Important fields:**

**Title & Description:**
- Can be changed freely
- No confirmation required

**URL:**
- Updates where document is located
- Confirmation modal shown

**Checksum & Algorithm:**
- Critical for integrity verification
- Confirmation modal warns of impact
- Change only if document version changed

**Workflow:**
1. Click "Edit Metadata"
2. Modify desired fields
3. Click "Save Changes"
4. If checksum/algorithm changed, confirm in modal
5. Success notification displayed

### Deleting a Document

**Soft Delete Behavior:**
- Document marked as deleted (`deleted_at` timestamp set)
- Signature history preserved
- Document no longer appears in public lists
- Admin can still view via direct URL
- Signatures CASCADE update (marked with `doc_deleted_at`)

**To delete:**
1. Go to document detail page (`/admin/docs/{docId}`)
2. Click "Delete Document" button
3. Confirm deletion in modal
4. Document moved to deleted state

**Note**: There is no "undelete" - this is permanent soft delete.

---

## Expected Signers

Expected signers are users you want to track for document completion.

### Adding Expected Signers

**From document detail page:**
1. Scroll to "Expected Signers" section
2. Click "Add Expected Signer" button
3. Enter email address(es):
   - Single: `alice@company.com`
   - Multiple: Comma-separated `alice@company.com,bob@company.com`
4. Optionally add notes
5. Click "Add"

**API endpoint:**
```http
POST /api/v1/admin/documents/{docId}/signers
Content-Type: application/json
X-CSRF-Token: {token}

{
  "emails": ["alice@company.com", "bob@company.com"],
  "notes": "Board members - Q1 2025"
}
```

**Constraints:**
- Email must be valid format
- UNIQUE constraint: Cannot add same email twice to same document
- Added by current admin user (tracked in `added_by`)

### Removing Expected Signers

**From document detail page:**
1. Find signer in Expected Signers list
2. Click "Remove" button next to their email
3. Confirm removal

**API endpoint:**
```http
DELETE /api/v1/admin/documents/{docId}/signers/{email}
X-CSRF-Token: {token}
```

**Effect:**
- Signer removed from expected list
- Does NOT delete their signature if they already signed
- Reminder history preserved in `reminder_logs`

### Tracking Completion Status

**Document Status API:**
```http
GET /api/v1/admin/documents/{docId}/status
```

**Response:**
```json
{
  "docId": "abc123",
  "expectedCount": 10,
  "signedCount": 7,
  "pendingCount": 3,
  "completionPercentage": 70.0
}
```

**Visual indicators:**
- Progress bar showing completion percentage
- Color-coded status: Green (signed), Orange (pending)
- Days since added (helps identify slow signers)

---

## Email Reminders

Email reminders are sent asynchronously via the `email_queue` system.

### Sending Reminders

**From document detail page:**
1. Click "Send Reminders" button
2. Modal opens with options:
   - **Send to**: All pending OR specific emails
   - **Document URL**: Pre-filled, can customize
   - **Language**: en, fr, es, de, it
3. Click "Send Reminders"
4. Confirmation: "X reminders queued for sending"

**API endpoint:**
```http
POST /api/v1/admin/documents/{docId}/reminders
Content-Type: application/json
X-CSRF-Token: {token}

{
  "emails": ["alice@company.com"],  // Optional: specific emails
  "docURL": "https://docs.company.com/policy.pdf",
  "locale": "en"
}
```

**Behavior:**
- Sends to ALL pending signers if `emails` not specified
- Sends to specific `emails` if provided (even if already signed)
- Emails queued in `email_queue` table
- Background worker processes queue
- Retry on failure (3 attempts, exponential backoff)

### Email Templates

**Location**: `backend/templates/emails/`

**Available templates:**
- `reminder.html` - HTML version
- `reminder.txt` - Plain text version

**Variables available in templates:**
- `{{.DocTitle}}` - Document title
- `{{.DocURL}}` - Document URL
- `{{.RecipientEmail}}` - Recipient's email
- `{{.SenderName}}` - Admin who sent reminder
- `{{.OrganisationName}}` - From ACKIFY_ORGANISATION

**Locales**: en, fr, es, de, it
- Template directory: `templates/emails/{locale}/`
- Fallback to default locale if translation missing

### Reminder History

**View reminder log:**
```http
GET /api/v1/admin/documents/{docId}/reminders
```

**Response:**
```json
{
  "reminders": [
    {
      "id": 123,
      "docId": "abc123",
      "recipientEmail": "alice@company.com",
      "sentAt": "2025-01-15T10:30:00Z",
      "sentBy": "admin@company.com",
      "templateUsed": "reminder",
      "status": "sent",
      "errorMessage": null
    }
  ]
}
```

**Status values:**
- `queued` - In email_queue, not yet processed
- `sent` - Successfully delivered
- `failed` - Delivery failed (check errorMessage)
- `bounced` - Email bounced back

**Tracking:**
- Last reminder sent date shown per signer
- Reminder count shown per signer
- Helps avoid over-sending

### Email Queue Monitoring

**Check queue status (PostgreSQL):**
```sql
-- Pending emails
SELECT id, to_addresses, subject, status, scheduled_for
FROM email_queue
WHERE status IN ('pending', 'processing')
ORDER BY priority DESC, scheduled_for ASC;

-- Failed emails
SELECT id, to_addresses, last_error, retry_count
FROM email_queue
WHERE status = 'failed';
```

**Worker configuration:**
- Batch size: 10 emails
- Poll interval: 5 seconds
- Max retries: 3
- Cleanup: 7 days retention

---

## Monitoring & Statistics

### Document-Level Statistics

**Completion tracking:**
- Expected vs Signed counts
- Pending signer list
- Completion percentage
- Average time to sign

**Reminder effectiveness:**
- Reminders sent count
- Success/failure rates
- Time between reminder and signature

### System-Wide Metrics

**PostgreSQL queries:**

```sql
-- Total documents
SELECT COUNT(*) FROM documents WHERE deleted_at IS NULL;

-- Total signatures
SELECT COUNT(*) FROM signatures;

-- Documents by completion status
SELECT
  CASE
    WHEN signed_count = expected_count THEN '100%'
    WHEN signed_count >= expected_count * 0.75 THEN '75-99%'
    WHEN signed_count >= expected_count * 0.50 THEN '50-74%'
    ELSE '<50%'
  END as completion_bracket,
  COUNT(*) as doc_count
FROM (
  SELECT
    d.doc_id,
    COUNT(DISTINCT es.email) as expected_count,
    COUNT(DISTINCT s.user_email) as signed_count
  FROM documents d
  LEFT JOIN expected_signers es ON d.doc_id = es.doc_id
  LEFT JOIN signatures s ON d.doc_id = s.doc_id AND s.user_email = es.email
  WHERE d.deleted_at IS NULL
  GROUP BY d.doc_id
) stats
GROUP BY completion_bracket;

-- Email queue statistics
SELECT status, COUNT(*), MIN(created_at), MAX(created_at)
FROM email_queue
GROUP BY status;
```

### Export Data

**Signatures for a document:**
```sql
COPY (
  SELECT s.user_email, s.user_name, s.signed_at, s.payload_hash
  FROM signatures s
  WHERE s.doc_id = 'your_doc_id'
  ORDER BY s.signed_at
) TO '/tmp/signatures_export.csv' WITH CSV HEADER;
```

**Expected signers status:**
```sql
COPY (
  SELECT
    es.email,
    CASE WHEN s.id IS NOT NULL THEN 'Signed' ELSE 'Pending' END as status,
    es.added_at,
    s.signed_at
  FROM expected_signers es
  LEFT JOIN signatures s ON es.doc_id = s.doc_id AND es.email = s.user_email
  WHERE es.doc_id = 'your_doc_id'
) TO '/tmp/expected_signers_export.csv' WITH CSV HEADER;
```

---

## Best Practices

### 1. Document Creation

✅ **Do:**
- Use descriptive titles
- Add clear descriptions
- Include document URL for easy access
- Store checksum for integrity verification
- Create expected signers list before sharing

❌ **Don't:**
- Use generic titles like "Document 1"
- Leave URL empty if document is accessible online
- Change checksums unless document actually changed

### 2. Expected Signers Management

✅ **Do:**
- Add expected signers before sending document link
- Use clear notes to explain why signers are expected
- Review pending signers regularly
- Remove signers who are no longer relevant

❌ **Don't:**
- Add hundreds of signers at once (use batches)
- Send reminders too frequently (max once per week)
- Remove signers who have already signed (preserve history)

### 3. Email Reminders

✅ **Do:**
- Wait 3-5 days before first reminder
- Send in recipient's preferred language
- Include clear document title and URL
- Track reminder history to avoid spam
- Send reminders during business hours

❌ **Don't:**
- Send daily reminders (causes fatigue)
- Send without checking if already signed
- Use generic subjects (personalize with doc title)
- Send outside business hours

### 4. Data Integrity

✅ **Do:**
- Regularly backup PostgreSQL database
- Verify checksums match actual documents
- Monitor email queue for failures
- Review unexpected signatures (may indicate broader interest)
- Export important signature data

❌ **Don't:**
- Delete documents with active signatures
- Modify timestamps manually in database
- Ignore failed email deliveries
- Change checksums without updating the document

### 5. Security

✅ **Do:**
- Limit admin access to trusted users only
- Use HTTPS in production (`ACKIFY_BASE_URL=https://...`)
- Rotate `ACKIFY_OAUTH_COOKIE_SECRET` periodically
- Monitor admin actions via application logs
- Use OAuth allowed domain restrictions

❌ **Don't:**
- Share admin credentials
- Run without HTTPS in production
- Disable CSRF protection
- Ignore authentication failures in logs

---

## Troubleshooting

### Common Issues

#### 1. Admin Link Not Visible

**Problem**: Can't see "Admin" link in navigation

**Solutions:**
- Verify email in `ACKIFY_ADMIN_EMAILS` environment variable
- Restart Ackify: `docker compose restart ackify-ce`
- Log out and log back in
- Check logs: `docker compose logs ackify-ce | grep admin`

#### 2. Emails Not Sending

**Problem**: Reminders queued but not delivered

**Diagnosis:**
```sql
SELECT * FROM email_queue WHERE status = 'failed' ORDER BY created_at DESC LIMIT 10;
```

**Solutions:**
- Check SMTP configuration (`ACKIFY_MAIL_HOST`, `ACKIFY_MAIL_USERNAME`, etc.)
- Verify SMTP credentials are correct
- Check email worker logs: `docker compose logs ackify-ce | grep email`
- Ensure `ACKIFY_MAIL_FROM` is valid sender address
- Test SMTP connection manually

#### 3. Duplicate Signer Error

**Problem**: "Email already exists as expected signer"

**Cause**: UNIQUE constraint on (doc_id, email)

**Solution**: This is expected behavior - each email can only be added once per document

#### 4. Checksum Mismatch

**Problem**: Users report checksum doesn't match

**Solutions:**
- Verify stored checksum matches actual document
- Check algorithm used (SHA-256, SHA-512, MD5)
- Recalculate checksum and update via Edit Metadata
- Ensure users are downloading correct version

#### 5. Document Not Appearing

**Problem**: Created document doesn't show in list

**Solutions:**
- Check if document was soft-deleted (`deleted_at IS NOT NULL`)
- Verify creation succeeded (check response/logs)
- Clear browser cache
- Check database: `SELECT * FROM documents WHERE doc_id = 'your_id';`

#### 6. Signature Already Exists

**Problem**: User can't sign document again

**Cause**: UNIQUE constraint (doc_id, user_sub) - one signature per user per document

**Solution**: This is expected - users cannot sign the same document twice

### Getting Help

**Logs:**
```bash
# Application logs
docker compose logs -f ackify-ce

# Database logs
docker compose logs -f ackify-db

# Email worker logs (grep email)
docker compose logs ackify-ce | grep -i email
```

**Database inspection:**
```bash
# Connect to PostgreSQL
docker compose exec ackify-db psql -U ackifyr ackify

# Useful queries
SELECT * FROM documents ORDER BY created_at DESC LIMIT 10;
SELECT * FROM expected_signers WHERE doc_id = 'your_doc_id';
SELECT * FROM email_queue WHERE status != 'sent' ORDER BY created_at DESC;
```

**Report issues:**
- GitHub: https://github.com/btouchard/ackify-ce/issues
- Include logs and error messages
- Describe expected vs actual behavior

---

## Quick Reference

### Environment Variables
```bash
ACKIFY_ADMIN_EMAILS=admin@company.com
ACKIFY_MAIL_HOST=smtp.gmail.com
ACKIFY_MAIL_FROM=noreply@company.com
```

### Key Endpoints
```
GET  /admin                              # Dashboard
GET  /admin/docs/{docId}                 # Document detail
POST /admin/documents/{docId}/signers    # Add signer
POST /admin/documents/{docId}/reminders  # Send reminders
PUT  /admin/documents/{docId}/metadata   # Update metadata
```

### Important Tables
- `documents` - Document metadata
- `signatures` - User signatures
- `expected_signers` - Who should sign
- `reminder_logs` - Email history
- `email_queue` - Async email queue

### Keyboard Shortcuts (Frontend)
- Search bar auto-focus on dashboard
- Enter to submit forms
- Esc to close modals

---

**Last Updated**: 2025-10-26
**Version**: 1.0.0
