MolinoPro

20260422_userRole-notes

Master Codebase Guidebook
Markdown + HTML Dev-Docs Renderer - Frontend Client Module

Default Index
Open README.md
Root: README.mdarchive
Milestones

Yes. These roles are still valid, but in Molino Index they should be reframed as capability profiles, not hard-wired dashboard silos.

Canonical role model for Molino Index

  1. Platform roles

These govern system authority.

export type PlatformRole = | "admin" | "operator" | "editor" | "member" | "guest";

Meaning: • admin • full system authority • manage users, visibility, publication, exports, projections, assignments • operator • business operations authority • manage trips, experiences, offers, orders, schedules, exports • editor • content/document/publication authority • manage virtual documents, publishing, magazine, editorial sections • member • authenticated normal user • can create own records where allowed, join trips, manage own bookings • guest • public / unauthenticated browsing surface

  1. Travel/commercial profile roles

These govern domain behavior in Trips/Experiences.

export type TravelProfile = | "traveller" | "organiser" | "provider" | "collaborator" | "partner";

Meaning: • traveller • books or joins trips/sessions • views bookings, schedules, confirmations • organiser • composes and runs trips • manages routes, estimates, offers, schedules • provider • responds to requests / supplies services • quote-side or service-side commercial contributor • collaborator • drafts experiences, plans, local content, support materials • contributes product supply or narrative assets • partner • broader external network role • guide, artisan, local operator, institution, affiliate

Mapping from your old roles

Your old app roles map well like this:

type LegacyRoleMap = { admin: "admin"; organiser: "organiser"; collaborator: "collaborator"; provider: "provider"; user: "traveller"; guest: "traveller"; };

But in Molino Index, do not use these old roles directly as the only authority model.

Use: • PlatformRole for access control • TravelProfile for trips/commercial UX • optional module-specific capabilities for finer control

Recommended capability model

Instead of branching the whole app by role-specific dashboard components, use one shared surface plus capability gates.

export type AppCapability = | "manage_users" | "manage_trips" | "manage_experiences" | "manage_group_sessions" | "manage_offers" | "manage_orders" | "manage_documents" | "publish_content" | "use_ai_tools" | "use_exports" | "manage_fareharbor_links" | "view_partner_tools" | "view_provider_tools" | "view_traveller_bookings";

Example presets:

export const ROLE_CAPABILITIES: Record<PlatformRole, AppCapability[]> = { admin: [ "manage_users", "manage_trips", "manage_experiences", "manage_group_sessions", "manage_offers", "manage_orders", "manage_documents", "publish_content", "use_ai_tools", "use_exports", "manage_fareharbor_links", "view_partner_tools", "view_provider_tools", "view_traveller_bookings", ], operator: [ "manage_trips", "manage_experiences", "manage_group_sessions", "manage_offers", "manage_orders", "manage_documents", "use_ai_tools", "use_exports", "manage_fareharbor_links", "view_partner_tools", "view_provider_tools", "view_traveller_bookings", ], editor: [ "manage_documents", "publish_content", "use_ai_tools", "use_exports", ], member: [ "view_traveller_bookings", ], guest: [], };

Then add optional travel-profile overlays:

export const PROFILE_CAPABILITIES: Record<TravelProfile, AppCapability[]> = { traveller: ["view_traveller_bookings"], organiser: [ "manage_trips", "manage_offers", "manage_documents", "use_exports", ], provider: [ "view_provider_tools", "manage_offers", ], collaborator: [ "manage_experiences", "manage_documents", "use_ai_tools", ], partner: [ "view_partner_tools", ], };

What this changes in practice

Replace this old pattern

switch (role.toLowerCase()) { case 'admin': return <AdminView />; case 'organiser': return <OrganiserView />; case 'collaborator': return <CollaboratorView />; case 'provider': return <ProviderView />; case 'user': case 'guest': return <GeneralUserView />; }

With this new pattern • one main route surface • sections/tools/buttons shown by capability • route-level and action-level guards • optional profile-specific panels inside the same shell

Example:

{can("manage_trips") && <TripOpsPanel />} {can("manage_experiences") && <ExperienceDraftPanel />} {can("view_provider_tools") && <ProviderRequestsPanel />} {can("view_traveller_bookings") && <MyBookingsPanel />} {can("publish_content") && <PublishingPanel />}

This is much better for Molino Index because: • trips, documents, exports, AI, publishing, CRM all overlap • one user may need multiple roles • dashboards should be composable, not siloed

Canonical user types by module

Trips • traveller • organiser • provider • collaborator • partner • admin

Experiences • collaborator • partner • organiser • admin

Documents / publishing • editor • organiser • collaborator • admin

Offers / orders / CRM • organiser • provider • operator • admin

Public landing • guest • traveller • partner prospect

Best canonical interpretation of your old views

GuestView / GeneralUserView

Becomes: • public + member traveller surface • featured trips • own bookings • own trip requests • planner entry point

CollaboratorView

Becomes: • experience drafting • city plans • supporting content • local supply contribution • document/AI-assisted contribution

ProviderView

Becomes: • quote/request surface • supplied service view • linked trips/sessions • service confirmation / commercial flow support

OrganiserView

Becomes: • main trips operations role • planner + offers + schedules + exports • central operational business view

AdminView

Becomes: • platform governance • publication, permissions, exports, sync, integrations, deploy-level concerns

Recommended final model

Use this as canonical:

export type UserRole = "admin" | "operator" | "editor" | "member" | "guest";

export type UserProfile = | "traveller" | "organiser" | "provider" | "collaborator" | "partner";

User record shape:

export type UserAccessModel = { role: UserRole; profiles: UserProfile[]; capabilities: AppCapability[]; };

This gives you: • one stable access model • one stable commercial/travel model • reusable user-type logic across modules • no mental lock into the old dashboard silos

Locked principle

Role controls authority. Profile controls workflow surface. Capability controls actual UI and actions.

If you want, next I can convert this into a Molino Index canonical roles.md with exact permissions matrix per module.