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