How TheCompanyApp ensures complete separation of company data.
Isolation Strategy
Core Principle: Every entity is scoped by companyID: UUID.
Enforcement: All data queries filtered by company identifier.
Company Scoping
Every company-scoped entity includes:
companyID: UUID - Unique identifier for the company
Optional: companyName: String - Denormalized for display
Example (InventoryItem entity):
<entity name="InventoryItem">
<attribute name="companyID" attributeType="UUID" usesScalarValueType="NO"/>
<attribute name="itemCode" attributeType="String"/>
<attribute name="itemName" attributeType="String"/>
<!-- ... other attributes ... -->
</entity>
All fetches must include companyID predicate:
Correct:
Wrong (no scoping):
Never fetch across companies unless explicitly intended (e.g., admin view in future).
SwiftUI Integration
@FetchRequest with Dynamic Predicate:
Result: View only displays orders for selected company.
Cross-Company Protection
Scenario: User Has Multiple Companies
User: Alice Companies:
Company A (companyID: abc-123)
Company B (companyID: def-456)
Data:
View Company A:
View Company B:
No Cross-Contamination: Company A data never appears in Company B views.
Shared Company Isolation
Scenario: Alice owns Company A, shares with Bob.
Alice's Perspective (Owner)
Fetch:
Result: Alice sees all company data (owner privilege + participant edits).
Bob's Perspective (Participant)
Fetch:
Result: Bob sees identical data to Alice.
Isolation: Bob cannot see Alice's other companies (Company B, Company C, etc.).
User-Specific Data: UserPass
Exception: UserPass is isolated by user, not shared.
Alice's UserPass:
Bob's UserPass:
Isolation Mechanism: Stored in Private Database, which is user-scoped by iCloud.
Fetch:
Isolation at CloudKit Level
Private Database
Scope: User-level
Data: User's owned companies + UserPass for all companies.
Access: Only the user (across their devices).
Example:
Alice's Private Database contains:
UserPass for Company C (shared by Charlie, but Alice's credentials)
Shared Database
Scope: Share-level (per CKShare)
Data: Companies shared to user + all shared company data.
Access: Owner + participants of the specific share.
Example:
Alice's Shared Database contains:
Company C (shared by Charlie)
Company C's inventory, orders, etc.
NO access to Company D (shared to someone else, not Alice)
Zone-Level Isolation: Each CKShare creates a separate zone. User can only read zones they're invited to.
Testing Isolation
Unit Test Example:
Expected Result: Each company sees only its own data.
Preventing Accidental Leakage
Code Review Checklist
Static Analysis
Consider:
SwiftLint custom rule to detect fetch requests without predicates
Runtime Assertion
Use in development to catch errors.
Related: Security Model, Company Scoping, Fetch Strategies