# Province data-sharing contract

Province access to a Unit's data requires all three controls at request time:

1. the relevant `province_unit_data_sharing` row is active and unexpired;
2. the Province has enabled the same `province_data_features` category; and
3. the actor has the category's scoped capability in the current Province.

Unit membership is never used as a substitute for a Province capability, and a
Province role is never used as a substitute for a Unit category permission.

| Category | Required capability | Existing default | Current enforcement |
|---|---|---|---|
| Events | `events.view` or `meeting.read` | Enabled for existing Province Units | Province Unit list and dashboard |
| Attendance | `reports.attendance` or `workspace.attendance` | Enabled for existing Province Units | Province Unit list and dashboard |
| Membership | `reports.membership` or `people.view` | Disabled | Operational dashboard returns unavailable rather than zero |
| Contacts | `contacts.read` or `people.view` | Disabled | Contract-ready; no Province contact reader is introduced |
| Candidates | `candidates.view` | Disabled | Contract-ready |
| Finance aggregates | `finance.read` | Disabled | Contract-ready |
| Welfare aggregates | `welfare.view` or `welfare.health` | Disabled | Contract-ready; no welfare detail roll-up exists |
| Documents | `documents.view` or `documents.read` | Disabled | Contract-ready; Province documents remain Province-owned |
| Group email | `communications.province.send` | Disabled | Contract-ready; no send route is introduced |
| Returns | `returns.view` or `returns.export` | Disabled | Province return export |

Every successful cross-Unit category evaluation records the actor, Province,
Unit, category, purpose and source workspace in `province_data_access_log`.
The Unit-facing API is `GET`/`POST /admin/api/province-data-sharing.php` in an
authenticated Unit context. It accepts only a closed category key and boolean
state; it derives Province and Unit from `TenantContext`.

## Rollout and rollback

1. Back up the database and run `C:\\xampp\\php\\php.exe bin\\migrate.php --status`.
2. Apply the migration with `C:\\xampp\\php\\php.exe bin\\migrate.php --apply`.
3. Confirm the three new tables exist and review the `events`/`attendance`
   transitional rows before enabling a sensitive category.
4. To revoke immediately, set the Unit category inactive through the Unit API;
   every later request re-evaluates the row. Do not delete audit rows.
5. A code rollback should be performed before a schema rollback. The additive
   tables can remain safely. Only drop them after a tested database restore and
   after confirming no audit or active sharing record must be retained.
