fix: macOS persistence, MySQL UUID keys, file picker blackout, and settings card color#35
Conversation
MySQL rejects TEXT/LONGTEXT as primary key columns without a key length (error 1170). All id columns and UUID foreign keys (user_id, customer_id, product_id, etc.) are always 36-char UUIDs, so map them to VARCHAR(36) via a new SyncColumnType.uuid enum value instead of LONGTEXT.
EULA acceptance now writes a plain marker file under applicationSupportDirectory instead of using flutter_secure_storage. The Keychain is overkill for non-sensitive preference data and was causing silent failures (and password prompts) on macOS. keychain-access-groups entitlement added to both Debug and Release entitlements so flutter_secure_storage (used for the license JWT) persists correctly across builds without prompting for the Mac login password each time.
NSOpenPanel captures window focus before Flutter can repaint after a dialog closes, leaving the window black. A one-frame delay lets the renderer settle before the native panel opens.
Backend card used surfaceVariant (#EEF2F7) while TextField widgets filled white (surface), creating a visible colour mismatch inside the same card. Switch to surface + border to match the field fill.
📝 WalkthroughWalkthroughMigrates EULA acceptance tracking from ChangesEULA File-Based Persistence and macOS Keychain Configuration
Sync Schema UUID Column Type
Settings Screen Minor Fixes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Preview deployed
Updates automatically on every push. |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib/data/sync/sync_table.dart (1)
17-22: 🩺 Stability & Availability | 🟠 MajorAdd ALTER TABLE logic to migrate existing MySQL sync tables, or confirm CREATE TABLE always failed with old LONGTEXT schema.
The
_ensureSchemamethod usesCREATE TABLE IF NOT EXISTS, which won't modify existing tables. If MySQL instances have these tables with the oldLONGTEXTschema, the VARCHAR(36) fix won't apply on upgrade—FK/PK columns would remainLONGTEXTand the error would persist. The Drift (SQLite) database has proper versioning and migration logic, but the MySQL sync tables lack an equivalent ALTER path. Either:
- Add ALTER TABLE statements to upgrade existing tables, or
- Confirm that the original LONGTEXT configuration always caused
CREATE TABLEto fail, ensuring no stale tables exist in production deployments.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/data/sync/sync_table.dart` around lines 17 - 22, The `mysqlType` getter has been updated to return VARCHAR(36) for UUID columns, but the `_ensureSchema` method uses CREATE TABLE IF NOT EXISTS which only creates new tables and doesn't modify existing ones. To ensure the schema fix applies to existing MySQL sync tables that may have the old LONGTEXT schema, you need to either add ALTER TABLE migration logic in the `_ensureSchema` method to update the column types for UUID, text, integer, and real columns from their old definitions to the new types defined in the `mysqlType` getter, or verify and document that the original LONGTEXT configuration always caused the CREATE TABLE operation to fail, ensuring no stale tables exist in production.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/providers/eula_provider.dart`:
- Around line 7-8: In the comment block for EULA acceptance in the
eula_provider.dart file, replace the em-dash (—) character with a regular hyphen
(-) in the phrase "EULA acceptance is not sensitive data — store as a plain
marker file rather". This aligns with the coding guideline that disallows
em-dashes in comments.
- Around line 11-20: Add error handling to the build() and accept() methods in
the EulaProvider class. In the build() method, wrap the file I/O operations (the
call to _markerFile() and existsSync()) in a try/catch block that returns false
when any exception occurs, treating storage failures as "not yet accepted"
rather than crashing. In the accept() method, wrap the _markerFile() call and
writeAsString() operation in a try/catch block to prevent state changes when the
file write fails, ensuring the caller can handle write failures appropriately
instead of silently succeeding with an inconsistent state.
In `@macos/Runner/Release.entitlements`:
- Around line 7-10: The keychain access group defined in the
Release.entitlements file is not being used by flutter_secure_storage, causing
Keychain operations to fail silently or with permission errors. In
auth_provider.dart, modify the MacOsOptions to include groupId: 'lk.getbms.bms'
(ensuring it matches the entitlements entry without the $(AppIdentifierPrefix)
prefix). In sync_provider.dart, update the FlutterSecureStorage() instantiation
to pass MacOsOptions with the same groupId. This ensures both the auth provider
and sync provider use the configured keychain access group consistently with the
entitlements definition.
---
Outside diff comments:
In `@lib/data/sync/sync_table.dart`:
- Around line 17-22: The `mysqlType` getter has been updated to return
VARCHAR(36) for UUID columns, but the `_ensureSchema` method uses CREATE TABLE
IF NOT EXISTS which only creates new tables and doesn't modify existing ones. To
ensure the schema fix applies to existing MySQL sync tables that may have the
old LONGTEXT schema, you need to either add ALTER TABLE migration logic in the
`_ensureSchema` method to update the column types for UUID, text, integer, and
real columns from their old definitions to the new types defined in the
`mysqlType` getter, or verify and document that the original LONGTEXT
configuration always caused the CREATE TABLE operation to fail, ensuring no
stale tables exist in production.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 8bac5965-1fc0-4886-b881-9f8d9174f2bc
📒 Files selected for processing (7)
lib/core/constants/app_constants.dartlib/data/sync/sync_table.dartlib/data/sync/sync_tables_registry.dartlib/features/settings/presentation/settings_screen.dartlib/providers/eula_provider.dartmacos/Runner/DebugProfile.entitlementsmacos/Runner/Release.entitlements
💤 Files with no reviewable changes (1)
- lib/core/constants/app_constants.dart
- Replace em-dash with hyphen in eula_provider.dart comment - Add try/catch to EulaNotifier.build() and accept(); accept() no longer updates state when the file write fails - Add groupId: 'lk.getbms.bms' to MacOsOptions in auth_provider.dart to match the keychain-access-groups entitlement - Add MacOsOptions(groupId: 'lk.getbms.bms') to SyncNotifier._storage so sync provider uses the same keychain access group Skipped: ALTER TABLE migration for UUID columns - CREATE TABLE with a LONGTEXT primary key always threw error 1170, so no stale tables exist.
Summary
Four fixes bundled together.
1. EULA and license key not persisting across launches
flutter_secure_storagewas failing silently on macOS causing password prompts, EULA reset, and license cleared on every restart.keychain-access-groupsentitlement toDebugProfile.entitlementsandRelease.entitlementsso the license JWT persists correctlyflutter_secure_storageto a plain marker file underapplicationSupportDirectory- EULA state is not sensitive data and does not belong in the Keychain2. MySQL sync fails with error 1170
SyncColumnType.textmapped toLONGTEXTin DDL. MySQL rejects TEXT columns as primary keys without a key length prefix.SyncColumnType.uuidmapping toVARCHAR(36)uuidfor primary keys and all UUID foreign key columns3. Window goes black when opening Import Database file picker
NSOpenPanelopened before Flutter finished repainting after the confirmation dialog closed.FilePicker.pickFiles()to let the renderer settle4. Backend settings card has a different background color than the text fields inside it
Card used
surfaceVariant(#EEF2F7) while TextFields filled withsurface(white), creating a visible color mismatch.surface+borderso the background is uniformTest plan
Summary by CodeRabbit
Release Notes