Skip to content

Conversation

@kevalyq
Copy link
Contributor

@kevalyq kevalyq commented Nov 1, 2025

Summary

Implements migrations for envelope key management (tenant_keys) and encrypted contact data (person) with blind indexes and full-text search support.

Changes

  • Dependencies: Install laravel/sanctum ^4.2 and spatie/laravel-permission ^6.22
  • tenant_keys migration: Store per-tenant DEK and index keys (wrapped with KEK) as PostgreSQL BYTEA
    • Columns: dek_wrapped, dek_nonce, idx_wrapped, idx_nonce, key_version (INT, default 1)
  • person migration: Encrypted PII fields with blind indexes for searchability
    • Encrypted fields: email_enc, phone_enc, note_enc (BYTEA/TEXT)
    • Blind indexes: email_idx, phone_idx (BYTEA) for equality search without decryption
    • Full-text search: note_tsv (tsvector) with GIN index
    • Composite indexes on (tenant_id, email_idx) and (tenant_id, phone_idx)
    • Foreign key: tenant_idtenant_keys.id with cascade delete
  • Test database setup: Switch phpunit.xml from SQLite to PostgreSQL (aligns with production)
  • Schema tests: 12 PEST tests verifying table structures, column types, indexes, and constraints

Testing

  • ✅ All 17 tests pass (including existing smoke tests)
  • ✅ Laravel Pint: code style compliant (PSR-12)
  • ✅ PHPStan level max: no errors (with @phpstan-ignore property.nonObject for DB result objects)
  • ✅ REUSE compliance: AGPL-3.0-or-later headers on all new files

Size

  • 394 LOC (migrations: 72, tests: 146, config: 3, composer: 173)
  • Under 600 LOC limit ✅

Relates to

Notes

  • Migrations use DB::statement() for PostgreSQL-specific types (tsvector, GIN index)
  • PHPStan ignores added for $column->property access on DB result objects (expected mixed type)
  • db_test database created manually for test environment (CI uses service container)

- Install laravel/sanctum ^4.2 and spatie/laravel-permission ^6.22
- Create tenant_keys table with envelope key storage (DEK/idx_key as BYTEA)
- Create person table with encrypted fields (BYTEA), blind indexes, and tsvector for FTS
- Add PostgreSQL GIN index on note_tsv for full-text search
- Add composite indexes on (tenant_id, email_idx) and (tenant_id, phone_idx)
- Switch phpunit.xml to use pgsql for testing (remove sqlite in-memory DB)
- Add comprehensive PEST schema tests for both tables
- Verify BYTEA types, tsvector type, indexes, and foreign key constraints

Relates to #50 (PR-1)
Copilot AI review requested due to automatic review settings November 1, 2025 17:07
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds encryption key management and encrypted person data storage with PostgreSQL-specific features. The changes transition from SQLite (in-memory) to PostgreSQL for testing and introduce two new database tables with cryptographic columns.

Key changes:

  • Added tenant_keys and person tables with binary encryption fields
  • Switched test database from SQLite to PostgreSQL
  • Added new dependencies: laravel/sanctum and spatie/laravel-permission

Reviewed Changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
database/migrations/2025_11_01_165633_create_tenant_keys_table.php Creates table for storing wrapped encryption keys with binary columns
database/migrations/2025_11_01_165901_create_person_table.php Creates person table with encrypted fields and PostgreSQL tsvector for search
tests/Feature/TenantKeysSchemaTest.php Tests schema structure and column types for tenant_keys table
tests/Feature/PersonSchemaTest.php Tests schema structure, indexes, and foreign keys for person table
phpunit.xml Changes test database from SQLite in-memory to PostgreSQL
composer.json Adds Laravel Sanctum and Spatie Permission packages
composer.lock Lock file updates for new dependencies

- Replace reusable workflow call with inline job + PostgreSQL service
- PostgreSQL 17-alpine service with health checks
- Configure DB env vars for test job (localhost:5432)
- Add driver check for PostgreSQL-specific tsvector/GIN index
- All 17 tests pass (no skipped tests)
- Pint, PHPStan, PEST all pass

Addresses Copilot review comment about database-specific SQL
Fixes CI test failures (was using SQLite, now PostgreSQL)
@kevalyq kevalyq requested a review from Copilot November 1, 2025 17:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 4 comments.

- Add explicit  return types to all test closures per Laravel guidelines
- Add test for note_enc column in PersonSchemaTest (TEXT type verification)
- Add DB_DATABASE=testing to phpunit.xml to avoid .env fallback confusion
- Replace reusable quality workflow with inline PostgreSQL service job
  (Quality Checks PEST tests were failing with SQLite, now use postgres:17-alpine)
- Both PHP CI and Quality Checks workflows now use identical PostgreSQL setup

This resolves all 5 Copilot review comments:
1. Driver check for tsvector (already fixed in previous commit)
2. Missing return types in test closures
3. Missing note_enc column test
4. DB_DATABASE env var missing
5. Quality workflow tests failing due to missing PostgreSQL service

All tests pass locally (18 passed, 42 assertions) with DDEV PostgreSQL.
Required status check expects 'PEST Tests / Run Tests' but step was named
'Run PEST tests'. Rename to 'Run Tests' to match branch protection rule.
@kevalyq kevalyq merged commit f9e130e into main Nov 1, 2025
12 checks passed
@kevalyq kevalyq deleted the feat/pr1-migrations-base-schema branch November 1, 2025 17:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants