User Types
Orchid has multiple distinct user types, each with their own login flow, portal, and permission scope. Understanding who each type is and what they can do is essential for understanding how the system works.
User type map
graph TD Agency["Fertility Agency"] Agency --> Admin["Agency Staff\n(Admin)"] Agency --> IP["Intended Parent\n(IP)"] Agency --> ED["Egg Donor\n(ED)"] Agency --> GC["Gestational Carrier\n(GC)"] Agency --> SD["Sperm Donor\n(SD)"] Agency --> Provider["External Provider\n(Clinic, Attorney, etc.)"] Agency --> Guest["Guest / Third Party"]
Admin -- "manages" --> IP & ED & GC & SD IP -- "matches with" --> ED & GC & SDAdmins (Agency Staff)
What they are: The people who work for the fertility agency — coordinators, case managers, and managers.
Portal: /admin/ — the primary administration interface.
What they can do:
- Manage all cases, contacts, and profiles
- Run the matching process (presenting donors/carriers to IPs)
- Review and approve/reject donor/carrier applications
- Communicate with clients via email and in-app messaging
- Generate reports, manage workflows, configure agency settings
Code representation: models.Admin in orchid/models/user.py
Session type check: session.get('user_type') will be one of:
'admin'— standard coordinator/case manager'company_admin'— agency-level manager with more permissions'admin-master'— Orchid’s own super-admin (can access all agencies)- Plus 20+ other role variants in
large_dicts._ADMIN_TYPES_DICT
Auth timeout: 4 hours of inactivity
Intended Parents (IPs)
What they are: The people who are trying to build a family using the agency’s services. They may be an individual, a couple, or a same-sex couple.
Portal: /user/ — the client portal, shared by all client types.
What they can do:
- Browse donor/carrier profiles when presented by the agency
- Accept or decline match proposals
- View their case status and journey timeline
- Complete forms assigned to them
- Upload and view documents
Code representation: models.User with user_type = 'IP' (or 'IP rep' for a representative)
Auth timeout: 20 minutes of inactivity
Egg Donors (EDs)
What they are: Women who donate their eggs. They apply through an intake form, complete a detailed profile, and (if accepted) are matched with an intended parent.
Portal: /user/ — same client portal as IPs, but with different content based on their role.
What they can do:
- Complete and update their detailed profile
- Submit forms (medical history, background checks, etc.)
- View their case status after being matched
Code representation: models.User with user_type = 'donor'; their profile is models.EDProfile
Gestational Carriers (GCs)
What they are: Women who carry pregnancies for intended parents. They go through a similar screening process to egg donors.
Portal: /user/
Code representation: models.User with user_type = 'surrogate'; profile is the GC portion of models.profile
Sperm Donors (SDs)
What they are: Men who donate sperm. Less common than ED or GC cases, but the system supports them fully.
Portal: /user/
Code representation: models.User with user_type = 'sperm_donor'
External Providers
What they are: Third-party professionals (IVF clinics, reproductive attorneys, escrow agencies, genetic counselors) who work on specific cases but are not part of the agency.
Portal: /provider/ — a separate, limited portal.
What they can do:
- View case information shared by the agency
- View documents and match sheets that the agency has explicitly shared
- Add notes on shared cases
Code representation: models.Provider (organization) + models.ProviderUser (individual login) in orchid/models/provider.py
Auth method: Token-based, separate from the session-based admin/user auth.
Guest / Third-Party Users
What they are: People who have been granted temporary access to view specific case information — for example, a family member of an intended parent.
Portal: /guest/
Code representation: models.NonParticipatingUser or models.ThirdPartyUser in orchid/models/user.py
Summary table
| Type | Portal | Code model | Session type | Timeout |
|---|---|---|---|---|
| Agency staff | /admin | Admin | 'admin', 'company_admin', etc. | 4 hours |
| Intended Parent | /user | User | 'IP', 'IP rep' | 20 min |
| Egg Donor | /user | User | 'donor' | 20 min |
| Gestational Carrier | /user | User | 'surrogate' | 20 min |
| Sperm Donor | /user | User | 'sperm_donor' | 20 min |
| Provider | /provider | Provider + ProviderUser | token-based | — |
| Guest | /guest | NonParticipatingUser / ThirdPartyUser | session | — |
How g knows who is logged in
In before_request, the session is checked and the appropriate g attribute is set:
g.admin # Set if an Admin is logged ing.user # Set if a User (IP/ED/GC/SD) is logged ing.provider # Set if a Provider is logged ing.np_user # Set if a NonParticipatingUser is logged inOnly one of these will be non-None for any given request. Route decorators (@authcheck) use this to gate access.