# Business rules — caredirect

Evidence date: 2026-10-19. Source: `git@bitbucket.org:overdrive/caredirect.git` at `5721fda` (`master`).

Rules below are recovered from application code. None were found in a dedicated business-rules document in the repository. Where a rule is deduced from code without an explicit product statement, it is marked **Inferred**. Do not treat Inferred rules as approved policy until a human confirms them.

## BR-001 — Two marketplace participant types

**Rule:** Participants are CareGivers or CareSeekers (WordPress roles `caregiver` and `careseeker`).

**Provenance:** Implemented (`themes/caredirect/inc/custom-roles.php`).

**Notes:** Standard WP roles `contributor`, `author`, and `editor` are removed on `init`. **Inferred** that the product only intends caregiver, careseeker, administrator (and whatever Facebook creates).

## BR-002 — Care service categories

**Rule:** Care work is categorised as Childcare, Adult and Senior Care, Home Care, and Pet Care.

**Provenance:** Implemented (`CC_Roles::install_category_data`).

## BR-003 — Care job roles and rates

**Rule:** Within categories, caregivers hold job roles (seeded from `base_roles.json`, e.g. Nanny, Au Pair, Night Nurse, Babysitter, Tutor) with base/experience rates and minimum booking fields on the role record.

**Provenance:** Implemented (`class.CC_Roles.php`, seed JSON).

**Unknown:** Whether live prices still match seed data; rates may have been edited in the database.

## BR-004 — Care role status lifecycle

**Rule:** A user–care-role link has status:

| Code | Text |
|---|---|
| 0 | Pending |
| 1 | Under Review |
| 2 | Approved |
| 3 | Declined |
| 4 | Cancelled |

Active roles for display/use are those with status `2` (`get_active_roles`).

**Provenance:** Implemented (`get_status_code` / `get_status_text`).

**Requires Confirmation:** `add_role()` writes status `2` immediately in the code path reviewed. How Pending/Under Review are reached in production is not fully evidenced.

## BR-005 — Public search only shows activated caregivers

**Rule:** Search results require `caregiver_activated` user meta equal to `'1'` and WordPress caregiver capability.

**Provenance:** Implemented (`search_caregivers` AJAX).

## BR-006 — CareGiver must complete onboarding before activation flags are set

**Rule:** CareGiver registration progress is tracked with `registration_step` (`experience` → `banking` → `approval`). Submitting approval emails administrators and sets `caregiver_activated` and `approval_sent`.

**Provenance:** Implemented (`update_personal_details`, `update_experience`, `update_banking`, `update_approval`).

**Inferred:** CareSeekers do not use this same activation gate (no parallel `careseeker_activated` found).

## BR-007 — Account activation before login completes for new signups

**Rule:** New accounts receive a 5-character activation key. Login of inactive users requires verification. Activation SMS/email resend is capped at 3 attempts (further attempts treated as spam).

**Provenance:** Implemented (`process_user_signup`, `is_user_active`, `verify_user_key`).

## BR-008 — Contact uniqueness and SA cellphone rules

**Rule:** Registration validation requires terms acceptance, first/last name, at least one contact method, matching passwords meeting password rules, and uniqueness checks. Cellphones are validated as South African numbers. Synthetic email pattern `{cell}@caredirect.co.za` is used in cellphone-login scenarios.

**Provenance:** Implemented (`validate_user_registration`, login username handling).

## BR-009 — Password reset limits

**Rule:** Password reset may be requested by email, SA ID number (`id_number` meta), or passport. Resets are limited to 3 per day (`password_resets` meta).

**Provenance:** Implemented (`ajax_reset` / `reset_password`).

## BR-010 — OTP for banking and contact changes

**Rule:** Changing banking details or contact methods requires a short-lived OTP (≈60s transient) delivered by the user’s preferred channel and submitted with the update.

**Provenance:** Implemented (`CC_OTP`, `trigger_contact_OTP`, banking/contact update paths).

**Inferred:** This is an anti-fraud / account-takeover control, not a legal requirement statement found in docs.

## BR-011 — Search matching on work location and availability meta

**Rule:** Search matches caregivers using:

- Keyword against login/email/display fields
- Region against `work_region` (string INSTR)
- City/area against `work_city`
- Date against `dates_enabled`
- Languages against `languages` meta
- Time window against `dates_repeat_data[date]['dates_time']` when times are provided

**Provenance:** Implemented (`search_caregivers`; 2020 region-search commits).

**Inferred:** Date and time are optional for search (2019 commits removed mandatory selection).

## BR-012 — Booking conflict and pending cleanup

**Rule:** Booking helpers check caregiver availability against existing bookings (`check_already_available_cg`). Pending bookings are cleaned up after 12 hours (theme logic).

**Provenance:** Implemented (`themes/caredirect/functions.php`).

**Unknown:** Full booking status vocabulary beyond pending → payment completed / approved on thank-you.

## BR-013 — Payment currency and return flow

**Rule:** Checkout charges in ZAR via PayGate PayWeb3; amount is sent in cents; return URL is the thank-you page; successful query updates booking payment and status.

**Provenance:** Implemented (`tpl-checkout.php`, `tpl-thankyou.php`).

**Requires Confirmation:** Whether hardcoded PayGate ID/key in checkout are production values or leftover samples.

## BR-014 — Caregiver restricted from some careseeker return URLs

**Rule:** Login success path contains logic to restrict caregivers from following certain return URLs intended for careseekers.

**Provenance:** Implemented (commented intent in `ajax_login`). Exact URL list should be re-read from code when changing login.

## BR-015 — Administrator receives caregiver applications

**Rule:** When a caregiver submits approval, all WordPress Administrators are emailed using the caregiver-application template.

**Provenance:** Implemented (`update_approval`).

**Note:** Code quality risk around `$user` / `$user_data` variables in that method was observed during inspection; production behaviour should be verified. Marked **Requires Confirmation** for runtime correctness.

## BR-016 — Facebook new users inherit role from redirect context

**Rule:** Facebook `createUser()` assigns `caregiver` or `careseeker` if the redirect URL contains those substrings; otherwise role assignment depends on that path’s defaults.

**Provenance:** Implemented (`CCFacebook`).

## Permissions / access (summary)

| Action | Who | Rule |
|---|---|---|
| View public search results | Anyone who can load the Search page | Only activated caregivers listed |
| Edit own caregiver profile tabs | User with `caregiver` | Incomplete profiles see limited tabs |
| Approve/reject care roles | Admin / privileged REST caller | `approve_role` / `reject_role` + logs |
| Manage Facebook settings | `manage_options` | Settings page gate |
| Most CareDirect REST routes | Logged-in user (capability checks vary) | Locations search is a documented exception |

Provenance: **Implemented** / **Inferred** as noted in `prd.md` auth section.

## Data retention / POPIA / privacy

No privacy policy, retention schedule, or POPIA handling document was found in the repository. Legal obligations around caregiver ID numbers, banking details, and ratings are **Unknown / Requires Confirmation**.

## Rules that must not be invented

The following look like product policy but are **not** established from code alone:

- Commission percentage or CareDirect fee model
- Mandatory criminal or ID verification as a legal gate (UI labels exist on checkout; enforcement beyond payment line items is Unknown)
- Service-level agreements for SMS delivery
- Geographic operating licence or industry accreditation

## Cross-document consistency

These rules align with `prd.md` FR-001–FR-009 and `features.md` caregiver search / booking sections. Discrepancies to resolve with humans:

1. CareSeeker signup slug `/become-a-seeker/` vs template naming `become-a-careseeker`.
2. Dual ratings table schemas.
3. `za_cities.region` used in queries but absent from install DDL/seed JSON.
4. PayGate sample vs production credentials.
