v2.0.0
Feature-complete milestone. PII encrypted at rest, and the full scoped roadmap is done.
PII encrypt-at-rest (Security) — #596, #598
The masked PII columns are now encrypted at rest:
Contact.email— encrypted, with a deterministicemail_hashblind index that carries equality lookups and uniqueness (encrypted ciphertext can't be uniquely indexed). Email search is now exact-match.Contact.phone_number+Company.phone_number— encrypted; phone search dropped (no blind index).
Money columns are intentionally left plaintext — they need database sort/range/aggregation for forecasting, and masking already hides them from the free role. An idempotent backfill encrypts existing rows on upgrade.
Since 1.0.0
Customer portal; SSO — OIDC and SAML, login and single-logout; per-team role enforcement (F4); attribute-based access control (territory scoping + field masking + PII encryption); detail views and CSV exports across the CRM.
Operational: run migrations on upgrade (email/phone rows are encrypted in place). APP_KEY rotation orphans the email blind index + ciphertext — re-run the backfill after a rotation.
Full suite 1141 passed / 1 skipped. PHPStan 0-new. Pint clean. MySQL-verified.