Skip to content

Commit 91aba3e

Browse files
committed
docs: add Doxygen infrastructure and tooling
Add complete Doxygen generation and validation infrastructure: **Configuration:** - Doxyfile - Doxygen configuration for HTML/LaTeX output - CLAUDE.md - Documentation standards and guidelines **Validation Scripts:** - tasks/check-doc-coverage.sh - Verify documentation coverage - tasks/validate-required-tags.sh - Ensure required tags present - tasks/doxygen-filter.sh - SQL-to-C++ comment filter for Doxygen **Mise Tasks:** - docs:generate - Generate API documentation - docs:validate - Run coverage and tag validation Source: phase-4-doxygen branch (commits 2e53216, ee96e15, e8debb0, etc.)
1 parent 7b85b2e commit 91aba3e

File tree

6 files changed

+444
-0
lines changed

6 files changed

+444
-0
lines changed

CLAUDE.md

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Development Commands
6+
7+
This project uses `mise` for task management. Common commands:
8+
9+
- `mise run build` (alias: `mise r b`) - Build SQL into single release file
10+
- `mise run test` (alias: `mise r test`) - Build, reset and run tests
11+
- `mise run postgres:up` - Start PostgreSQL container
12+
- `mise run postgres:down` - Stop PostgreSQL containers
13+
- `mise run reset` - Reset database state
14+
- `mise run clean` (alias: `mise r k`) - Clean release files
15+
- `mise run docs:generate` - Generate API documentation (requires doxygen)
16+
- `mise run docs:validate` - Validate documentation coverage and tags
17+
18+
### Testing
19+
- Run all tests: `mise run test`
20+
- Run specific test: `mise run test --test <test_name>`
21+
- Run tests against specific PostgreSQL version: `mise run test --postgres 14|15|16|17`
22+
- Tests are located in `*_test.sql` files alongside source code
23+
24+
### Build System
25+
- Dependencies are resolved using `-- REQUIRE:` comments in SQL files
26+
- Build outputs to `release/` directory:
27+
- `cipherstash-encrypt.sql` - Main installer
28+
- `cipherstash-encrypt-supabase.sql` - Supabase-compatible installer
29+
- `cipherstash-encrypt-uninstall.sql` - Uninstaller
30+
31+
## Project Architecture
32+
33+
This is the **Encrypt Query Language (EQL)** - a PostgreSQL extension for searchable encryption. Key architectural components:
34+
35+
### Core Structure
36+
- **Schema**: All EQL functions/types are in `eql_v2` PostgreSQL schema
37+
- **Main Type**: `eql_v2_encrypted` - composite type for encrypted columns (stored as JSONB)
38+
- **Configuration**: `eql_v2_configuration` table tracks encryption configs
39+
- **Index Types**: Various encrypted index types (blake3, hmac_256, bloom_filter, ore variants)
40+
41+
### Directory Structure
42+
- `src/` - Modular SQL components with dependency management
43+
- `src/encrypted/` - Core encrypted column type implementation
44+
- `src/operators/` - SQL operators for encrypted data comparisons
45+
- `src/config/` - Configuration management functions
46+
- `src/blake3/`, `src/hmac_256/`, `src/bloom_filter/`, `src/ore_*` - Index implementations
47+
- `tasks/` - mise task scripts
48+
- `tests/` - Test files (PostgreSQL 14-17 support)
49+
- `release/` - Generated SQL installation files
50+
51+
### Key Concepts
52+
- **Dependency System**: SQL files declare dependencies via `-- REQUIRE:` comments
53+
- **Encrypted Data**: Stored as JSONB payloads with metadata
54+
- **Index Terms**: Transient types for search operations (blake3, hmac_256, etc.)
55+
- **Operators**: Support comparisons between encrypted and plain JSONB data
56+
- **CipherStash Proxy**: Required for encryption/decryption operations
57+
58+
### Testing Infrastructure
59+
- Tests run against PostgreSQL 14, 15, 16, 17 using Docker containers
60+
- Container configuration in `tests/docker-compose.yml`
61+
- Test helpers in `tests/test_helpers.sql`
62+
- Database connection: `localhost:7432` (cipherstash/password)
63+
- **Rust/SQLx Tests**: Modern test framework in `tests/sqlx/` (see README there)
64+
65+
## Project Learning & Retrospectives
66+
67+
Valuable lessons and insights from completed work:
68+
69+
- **SQLx Test Migration (2025-10-24)**: See `docs/retrospectives/2025-10-24-sqlx-migration-retrospective.md`
70+
- Migrated 40 SQL assertions to Rust/SQLx (100% coverage)
71+
- Key insights: Blake3 vs HMAC differences, batch-review pattern effectiveness, coverage metric definitions
72+
- Lessons: TDD catches setup issues, infrastructure investment pays off, code review after each batch prevents compound errors
73+
74+
## Documentation Standards
75+
76+
### Doxygen Comments
77+
78+
All SQL functions and types must be documented using Doxygen-style comments:
79+
80+
- **Comment Style**: Use `--!` prefix for Doxygen comments (not `--`)
81+
- **Required Tags**:
82+
- `@brief` - Short description (required for all functions/files)
83+
- `@param` - Parameter description (required for functions with parameters)
84+
- `@return` - Return value description (required for functions with non-void returns)
85+
- **Optional Tags**:
86+
- `@throws` - Exception conditions
87+
- `@note` - Important notes or caveats
88+
- `@warning` - Warning messages (e.g., for DDL-executing functions)
89+
- `@see` - Cross-references to related functions
90+
- `@example` - Usage examples
91+
- `@internal` - Mark internal/private functions
92+
- `@file` - File-level documentation
93+
94+
### Documentation Example
95+
96+
```sql
97+
--! @brief Create encrypted index configuration
98+
--!
99+
--! Initializes a new encrypted index configuration for a table column.
100+
--! The configuration tracks encryption settings and index types.
101+
--!
102+
--! @param p_table_name text Table name (schema-qualified)
103+
--! @param p_column_name text Column name to encrypt
104+
--! @param p_index_type text Type of encrypted index (blake3, hmac_256, etc.)
105+
--!
106+
--! @return uuid Configuration ID for the created index
107+
--!
108+
--! @throws unique_violation If configuration already exists for this column
109+
--!
110+
--! @note This function executes DDL and modifies database schema
111+
--! @see eql_v2.activate_encrypted_index
112+
--!
113+
--! @example
114+
--! -- Create blake3 index configuration
115+
--! SELECT eql_v2.create_encrypted_index(
116+
--! 'public.users',
117+
--! 'email',
118+
--! 'blake3'
119+
--! );
120+
CREATE FUNCTION eql_v2.create_encrypted_index(...)
121+
```
122+
123+
### Validation Tools
124+
125+
Verify documentation quality:
126+
127+
```bash
128+
# Using mise (recommended - validates coverage and tags)
129+
mise run docs:validate
130+
131+
# Or run individual scripts directly
132+
tasks/check-doc-coverage.sh # Check 100% coverage
133+
tasks/validate-required-tags.sh # Verify @brief, @param, @return tags
134+
tasks/validate-documented-sql.sh # Validate SQL syntax (requires database)
135+
```
136+
137+
### Template Files
138+
139+
Template files (e.g., `version.template`) must be documented. The Doxygen comments are automatically included in generated files during build.
140+
141+
## Development Notes
142+
143+
- SQL files are modular - put operator wrappers in `operators.sql`, implementation in `functions.sql`
144+
- All SQL files must have `-- REQUIRE:` dependency declarations
145+
- Test files end with `_test.sql` and live alongside source files
146+
- Build system uses `tsort` to resolve dependency order
147+
- Supabase build excludes operator classes (not supported)
148+
- **Documentation**: All functions/types must have Doxygen comments (see Documentation Standards above)

Doxyfile

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Doxyfile for Encrypt Query Language (EQL)
2+
# PostgreSQL extension for searchable encryption
3+
4+
#---------------------------------------------------------------------------
5+
# Project Settings
6+
#---------------------------------------------------------------------------
7+
8+
PROJECT_NAME = "Encrypt Query Language (EQL)"
9+
PROJECT_NUMBER = "2.x"
10+
PROJECT_BRIEF = "PostgreSQL extension for searchable encryption"
11+
12+
OUTPUT_DIRECTORY = docs/api
13+
CREATE_SUBDIRS = NO
14+
15+
#---------------------------------------------------------------------------
16+
# Build Settings
17+
#---------------------------------------------------------------------------
18+
19+
GENERATE_HTML = YES
20+
GENERATE_LATEX = NO
21+
GENERATE_XML = NO
22+
GENERATE_MAN = NO
23+
24+
HTML_OUTPUT = html
25+
HTML_FILE_EXTENSION = .html
26+
HTML_DYNAMIC_SECTIONS = YES
27+
28+
#---------------------------------------------------------------------------
29+
# Input Settings
30+
#---------------------------------------------------------------------------
31+
32+
INPUT = src/
33+
FILE_PATTERNS = *.sql *.template
34+
RECURSIVE = YES
35+
EXCLUDE_PATTERNS = *_test.sql
36+
37+
# Treat SQL files as C++ for parsing
38+
EXTENSION_MAPPING = sql=C++ template=C++
39+
40+
# CRITICAL: Input filter to convert SQL comments (--!) to C++ style (//!)
41+
# This is REQUIRED for Doxygen to recognize SQL comments
42+
INPUT_FILTER = "tasks/doxygen-filter.sh"
43+
FILTER_SOURCE_FILES = YES
44+
45+
#---------------------------------------------------------------------------
46+
# Extraction Settings
47+
#---------------------------------------------------------------------------
48+
49+
EXTRACT_ALL = YES
50+
EXTRACT_PRIVATE = YES
51+
EXTRACT_STATIC = YES
52+
53+
HIDE_UNDOC_MEMBERS = NO
54+
HIDE_UNDOC_CLASSES = NO
55+
56+
SHOW_FILES = YES
57+
SHOW_NAMESPACES = YES
58+
59+
#---------------------------------------------------------------------------
60+
# Documentation Settings
61+
#---------------------------------------------------------------------------
62+
63+
JAVADOC_AUTOBRIEF = YES
64+
OPTIMIZE_OUTPUT_FOR_C = YES
65+
66+
#---------------------------------------------------------------------------
67+
# Warning Settings
68+
#---------------------------------------------------------------------------
69+
70+
QUIET = NO
71+
WARNINGS = YES
72+
WARN_IF_UNDOCUMENTED = NO
73+
WARN_IF_DOC_ERROR = YES
74+
WARN_NO_PARAMDOC = NO
75+
76+
#---------------------------------------------------------------------------
77+
# Source Browsing
78+
#---------------------------------------------------------------------------
79+
80+
SOURCE_BROWSER = YES
81+
INLINE_SOURCES = NO
82+
REFERENCED_BY_RELATION = YES
83+
REFERENCES_RELATION = YES
84+
85+
#---------------------------------------------------------------------------
86+
# Alphabetical Index
87+
#---------------------------------------------------------------------------
88+
89+
ALPHABETICAL_INDEX = YES
90+
91+
#---------------------------------------------------------------------------
92+
# Search Engine
93+
#---------------------------------------------------------------------------
94+
95+
SEARCHENGINE = YES

mise.toml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,21 @@ run = """
2323
rm -f release/cipherstash-encrypt-uninstall.sql
2424
rm -f release/cipherstash-encrypt.sql
2525
"""
26+
27+
[tasks."docs:generate"]
28+
description = "Generate API documentation with Doxygen"
29+
run = """
30+
echo "Generating API documentation..."
31+
doxygen Doxyfile
32+
echo "Documentation generated at docs/api/html/index.html"
33+
"""
34+
35+
[tasks."docs:validate"]
36+
description = "Validate SQL documentation"
37+
run = """
38+
echo "Checking documentation coverage..."
39+
./tasks/check-doc-coverage.sh
40+
echo ""
41+
echo "Validating required tags..."
42+
./tasks/validate-required-tags.sh
43+
"""

tasks/check-doc-coverage.sh

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/bin/bash
2+
# tasks/check-doc-coverage.sh
3+
# Checks documentation coverage for SQL files
4+
5+
set -e
6+
7+
cd "$(dirname "$0")/.."
8+
9+
echo "# SQL Documentation Coverage Report"
10+
echo ""
11+
echo "Generated: $(date)"
12+
echo ""
13+
14+
total_sql_files=0
15+
documented_sql_files=0
16+
17+
# Check .sql files
18+
for file in $(find src -name "*.sql" -not -name "*_test.sql" | sort); do
19+
# Skip auto-generated files
20+
if grep -q "^-- AUTOMATICALLY GENERATED FILE" "$file" 2>/dev/null; then
21+
echo "- $file: ⊘ Auto-generated (skipped)"
22+
continue
23+
fi
24+
25+
total_sql_files=$((total_sql_files + 1))
26+
27+
if grep -q "^--! @brief" "$file" 2>/dev/null; then
28+
echo "- $file: ✓ Documented"
29+
documented_sql_files=$((documented_sql_files + 1))
30+
else
31+
echo "- $file: ✗ No documentation"
32+
fi
33+
done
34+
35+
# Check .template files
36+
total_template_files=0
37+
documented_template_files=0
38+
39+
for file in $(find src -name "*.template" | sort); do
40+
total_template_files=$((total_template_files + 1))
41+
42+
if grep -q "^--! @brief" "$file" 2>/dev/null; then
43+
echo "- $file: ✓ Documented"
44+
documented_template_files=$((documented_template_files + 1))
45+
else
46+
echo "- $file: ✗ No documentation"
47+
fi
48+
done
49+
50+
total_files=$((total_sql_files + total_template_files))
51+
documented_files=$((documented_sql_files + documented_template_files))
52+
53+
echo ""
54+
echo "## Summary"
55+
echo ""
56+
echo "- SQL files: $documented_sql_files/$total_sql_files"
57+
echo "- Template files: $documented_template_files/$total_template_files"
58+
echo "- Total files: $documented_files/$total_files"
59+
60+
if [ $total_files -gt 0 ]; then
61+
coverage=$((documented_files * 100 / total_files))
62+
echo "- Coverage: ${coverage}%"
63+
else
64+
coverage=0
65+
fi
66+
67+
echo ""
68+
69+
if [ $coverage -eq 100 ]; then
70+
echo "✅ 100% documentation coverage achieved!"
71+
exit 0
72+
else
73+
echo "⚠️ Documentation coverage: ${coverage}%"
74+
exit 1
75+
fi

tasks/doxygen-filter.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
# Doxygen input filter for SQL files
3+
# Converts SQL-style comments (--!) to C++-style comments (//!)
4+
5+
sed 's/^--!/\/\/!/g' "$1"

0 commit comments

Comments
 (0)