Bite 30B — Global Person and Person–Tenant Membership Foundation - RodrigoMattosoSilveira/EnterpriseRemoteSystems GitHub Wiki

Bite 30B — Global Person and Person–Tenant Membership Foundation

Manual Verification Checklist Before Promotion

Issue branch: 691-bite-30b-global-person-and-persontenant-membership-foundation Baseline SHA: d13d59292cd50955b8513c3590c7b9fba4101222

Scope

These tests verify only the behavior introduced by Bite 30B:

  • Global Person foundation
  • Person–Tenant Membership
  • Tenant-confidential membership lookup
  • Tenant Administrator membership creation
  • Global Person field synchronization
  • Tenant-specific Person information isolation
  • Migration compatibility with existing People

Do not use this bite to validate the final Bite 30 behavior for:

  • multiple Actors per Authentication Account;
  • tenant switching by Actor;
  • intrinsic self-service authorization;
  • removal of the PERSON Role;
  • Collaborator → Membership cutover;
  • Person + Tenant financial ownership;
  • Application Administrator control-plane isolation;
  • Tenant Support Access Leases.

Those belong to later Bite 30 implementation bites.


✔︎ 1. Existing People Survived the Migration

Procedure

  • [✔︎] Sign in using a normal administrative account that could view People before Bite 30B.
  • [✔︎] Open /people.
  • [✔︎] Verify that existing People are still listed.
  • [✔︎] Open several existing People.
  • [✔︎] Verify that their normal information is present.
  • [✔︎] Search for existing People by name/nickname using the existing search behavior.

Expected

  • [✔︎] Existing People were not lost.
  • [✔︎] Existing People remain associated with their original Tenant.
  • [✔︎] Normal People screens continue to function.
  • [✔︎] No obvious duplicate People appeared because of the migration.
  • [✔︎] No Person from another Tenant unexpectedly appears.

✔︎ 2. Create a New Person in Tenant A

Use a disposable Person with globally unique identifying information.

Record:

Tenant A: Byte 28A Manual Test
Person name: Paulo Jose
Nickname: PJ
CPF: 59430164732
Email: [email protected]
Cellular: 86972193125

Procedure

  • [✔︎] In Tenant A, create a new Person through the existing People workflow.
  • [✔︎] Save the Person.
  • [✔︎] Return to the People list.
  • [✔︎] Search for the Person.
  • [✔︎] Open the Person again.

Expected

  • [✔︎] Person creation succeeds.
  • [✔︎] The Person appears in Tenant A.
  • [✔︎] The Person can be found normally.
  • [✔︎] Reopening the Person shows the values entered.
  • [✔︎] There is no visible indication that the implementation internally created both a global Person and Person–Tenant Membership.
  • [✔︎] Existing Bite 28 People UX remains usable.

✔︎ 3. Find the Existing Global Person from Tenant B

This is the most important new 30B workflow.

Using the Person created in Test 2:

Procedure

  • [✔︎] Switch/login to Tenant B as a Tenant Administrator.
  • [✔︎] Open the People workflow for adding an existing Person.
  • [✔︎] Search using sufficiently specific identifying information for the Person created in Tenant A.
  • [✔︎] Verify that the Person can be located.

Expected

  • [✔︎] ERS finds the existing global Person.
  • [✔︎] ERS does not say or imply that the Person belongs to Tenant A.
  • [✔︎] ERS does not display Tenant A's name.
  • [✔︎] ERS does not display Tenant A's Person status.
  • [✔︎] ERS does not display Tenant A's notes.
  • [✔︎] ERS does not display Tenant A's Collaborator information.
  • [✔︎] ERS does not display Tenant A's roles, Actor, Earnings, Expenses, or other tenant relationships.

The result should communicate essentially:

This Person exists and may be added to your Tenant.

It must not communicate:

This Person belongs to Tenant A.


✔︎ 4. Create the Person–Tenant Membership in Tenant B

Continue with the Person found in Test 3.

Procedure

  • Use
    • Account: a Tenant Administrator
    • Tenant: Tenant B (default)
    • Do not use: bootstrap-admin / APPLICATION_ADMIN
  • [✔︎] Select the existing Person.
  • [✔︎] Create/add the Person to Tenant B.
  • [✔︎] Return to Tenant B's People list.
  • [✔︎] Search for the Person.
  • [✔︎] Open the Person.

Expected

  • [✔︎] Membership creation succeeds.
  • [✔︎] The Person now appears normally in Tenant B.
  • [✔︎] No second global Person appears to have been created.
  • [✔︎] Tenant B has its own tenant-specific Person state.
  • [✔︎] Tenant A continues to see the same Person normally.

✔︎ 5. Prevent Duplicate Membership

Remain in Tenant B.

Procedure

  • [✔︎] Use
    • Account: a Tenant Administrator
    • Tenant: Tenant B (default)
    • Do not use: bootstrap-admin / APPLICATION_ADMIN
  • [✔︎] Go to /people.
  • [✔︎] Click Add existing.
  • [✔︎] Search for the same global Person you just added in Test 4, for example, [email protected].

Expected

One of these UX patterns is acceptable:

  • [✔︎] the Person is excluded from eligible results; or
  • ERS reports clearly that the Person already belongs to this Tenant.

But:

  • [✔︎] no second Person–Tenant Membership is created;
  • [✔︎] no duplicate Person appears in Tenant B;
  • [✔︎] no server/internal error is shown.

✔︎ 6. Global Person Information Propagates Across Tenants

The same Person should now participate in Tenant A and Tenant B.

Choose a harmless globally shared field such as the Person's name or cellular number.

Record the original value:

Field: Cellular
Original value: 86972193125
New value: 86972193152

Procedure

  • [✔︎] In Tenant A, edit the chosen global Person field.
  • [✔︎] Save.
  • [✔︎] Verify Tenant A immediately shows the new value.
  • [✔︎] Switch/login to Tenant B.
  • [✔︎] Find the same Person.
  • [✔︎] Open the Person.

Expected

  • [✔︎] Tenant B displays the updated global value.
  • [✔︎] Tenant B does not continue displaying a stale copy of the old value.
  • [✔︎] Search/list results in Tenant B also use the updated value where applicable.
  • [✔︎] Only one conceptual Person exists.

This verifies the fundamental Bite 30A/30B rule:

Maria is one global Person, not independent tenant-owned copies of Maria.


✔︎ 7. Tenant-Specific Information Does NOT Propagate

Choose tenant-specific fields, particularly status and/or notes.

Record:

Tenant A status:
Tenant A notes:

Tenant B status:
Tenant B notes:

Procedure

  • [✔︎] In Tenant A, change the Person's tenant-specific status or notes.
  • [✔︎] Save.
  • [✔︎] Verify Tenant A shows the new tenant-specific value.
  • [✔︎] Open the same Person from Tenant B.

Expected

  • [✔︎] Tenant B's status did not change.
  • [✔︎] Tenant B's notes did not change.
  • [✔︎] Tenant B cannot see Tenant A's notes.
  • [✔︎] Tenant B retains its own tenant-specific state.

This is a critical confidentiality test.


✔︎ 8. Cross-Tenant Membership Confidentiality

Using the Person who now belongs to both Tenant A and Tenant B:

Procedure

As Tenant A Administrator:

  • [✔︎] Search for the Person.
  • [✔︎] Open the Person.
  • [✔︎] Inspect all visible tabs, cards, labels, metadata, and actions.

Repeat from Tenant B.

Expected

From Tenant A:

  • [✔︎] no mention of Tenant B;
  • [✔︎] no list of the Person's other memberships;
  • [✔︎] no indication of the number of Tenants the Person participates in;
  • [✔︎] no Tenant-B status or notes;
  • [✔︎] no Tenant-B business relationship information.

From Tenant B, the equivalent must hold for Tenant A.

Failure of this test should block promotion.


✔︎ 9. Membership Creation Requires Tenant Administrator

Use an account that has People-related access but is not a Tenant Administrator, if one is readily available.

Procedure

  • [✔︎] Sign in as the non-Tenant-Administrator.
  • [✔︎] Attempt to reach/use the Add Existing Person / Membership creation workflow.

Expected

  • [✔︎] The user cannot create a Person–Tenant Membership.
  • [✔︎] The UI either hides/disables the operation or the server rejects it cleanly.
  • [✔︎] No Membership is created.

This verifies the agreed invariant:

Only a Tenant Administrator may create a Person–Tenant Membership.


✔︎ 10. Global Search Does Not Behave Like a Person Directory

The global lookup exists to locate a specific known Person, not to expose the global ERS population.

Procedure

From the Add Existing Person workflow:

  • [✔︎] Use
    • Account: a Tenant Administrator
    • Tenant: Tenant B (default)
    • Do not use: bootstrap-admin / APPLICATION_ADMIN
  • [✔︎] Go to People → Add existing.
  • [✔︎] Try an empty search.
  • [✔︎] Try a very short or vague search.
  • [✔︎] Try characters such as % or _.
  • [✔︎] Attempt to use these searches to enumerate many People.

Expected

  • [✔︎] ERS does not expose a global Person directory.
  • [✔︎] Wildcard-like input does not return arbitrarily large Person populations.
  • [✔︎] The feature requires meaningful identifying search input.
  • [✔︎] No Tenant relationships are exposed in returned results.

✔︎ 11. Existing Collaborator Workflows Still Work

Bite 30F will eventually change Collaborator creation to depend directly on Membership. Bite 30B must not prematurely break the existing workflow.

Procedure

  • [✔︎] Use
    • Account: a Tenant Administrator
    • Tenant: Tenant B (default)
    • Do not use: bootstrap-admin / APPLICATION_ADMIN
  • [✔︎] Open /collaborators.
  • [✔︎] Verify existing Collaborators remain visible.
  • [✔︎] Open an existing Collaborator.
  • Exercise the existing eligible-Person search sufficiently to verify that the screen still works.

Expected

  • [✔︎] Existing Collaborators remain usable.
  • [✔︎] No missing-Person errors appear because of the global-Person migration.
  • [✔︎] No cross-tenant Person leakage appears in Collaborator searches.

Do not require the final Membership-based Collaborator UX yet; that is Bite 30F.


✔︎ 12. Existing Financial History Still Works

Bite 30G will eventually move enduring financial ownership to Person + Tenant. Bite 30B must preserve the existing behavior until that cutover.

Procedure

For one existing Person/Collaborator with financial history:

  • [✔︎] Use
    • Account: a Tenant Administrator
    • Tenant: Tenant B (default)
    • Do not use: bootstrap-admin / APPLICATION_ADMIN
  • [✔︎] Open the Current Account or other existing Earnings view.
  • [✔︎] Verify existing Earnings remain visible.
  • [✔︎] Verify existing Expenses remain visible.
  • If available, inspect a historical Collaborator's financial history.

Expected

  • [✔︎] Existing financial data remains intact.
  • [✔︎] No records disappeared because of the new global Person foundation.
  • [✔︎] No financial records belonging to another Tenant appear.

✔︎ 13. Refresh and Navigation Regression Check

Procedure

For the new multi-tenant Person:

  • [✔︎] Open the Person in Tenant A.
  • [✔︎] Refresh the browser.
  • [✔︎] Navigate away and back.
  • [✔︎] Sign out and sign in again.
  • [✔︎] Repeat in Tenant B.

Expected

  • [✔︎] Correct Person information remains visible.
  • [✔︎] Tenant-specific information remains correctly isolated.
  • [✔︎] Global information remains synchronized.
  • [✔︎] No duplicate records appear.
  • [✔︎] No unexpected 401, 403, 404, or 500 responses appear.

14. Browser Console / Network Sanity Check

During the scenarios above:

  • [✔︎] Keep the browser developer console open.
  • [✔︎] Inspect failed network requests if any occur.

Expected

  • [✔︎] No unexpected JavaScript errors.
  • [✔︎] No unexpected 401 Unauthorized.
  • [✔︎] No unexpected 403 Forbidden.
  • [✔︎] No 500 Internal Server Error.
  • [✔︎] No requests or responses visibly contain membership information belonging to another Tenant.

Promotion Gate

Bite 30B is ready for promotion when:

  • make local-check passes.
  • Existing People survived migration.
  • New Person creation works.
  • An existing global Person can be added to a second Tenant.
  • Only a Tenant Administrator can create that Membership.
  • Duplicate Membership is prevented.
  • Global Person fields propagate between memberships.
  • Tenant-specific status/notes remain isolated.
  • Tenant A cannot discover the Person's relationship with Tenant B.
  • Existing Collaborator behavior remains operational.
  • Existing financial history remains operational.
  • No significant browser-console/network regression is found.

Promotion-blocking defects

Do not promote if any of the following occurs:

  • Tenant A can discover that the Person participates in Tenant B.
  • Tenant-specific notes/status propagate between Tenants.
  • Adding an existing Person creates another global Person.
  • The same Person can acquire duplicate Memberships in one Tenant.
  • A non-Tenant-Administrator can create Memberships.
  • Updating global Person information leaves another Tenant displaying stale authoritative identity data.
  • Existing People, Collaborators, Earnings, or Expenses disappear after the migration.
  • Cross-tenant business or financial data becomes visible.
  • Any normal workflow produces an unexpected 500 error.

If all of the promotion-gate checks above pass, I would consider Bite 30B ready for promotion.