Files
meal-planner/src/collections/Users/index.ts

142 lines
3.5 KiB
TypeScript

import type { CollectionConfig } from 'payload'
import { createAccess } from './access/create'
import { readAccess } from './access/read'
import { updateAndDeleteAccess } from './access/updateAndDelete'
import { externalUsersLogin } from './endpoints/externalUsersLogin'
import { ensureUniqueUsername } from './hooks/ensureUniqueUsername'
import { isSuperAdmin } from '@/access/isSuperAdmin'
import { setCookieBasedOnDomain } from './hooks/setCookieBasedOnDomain'
import { tenantsArrayField } from '@payloadcms/plugin-multi-tenant/fields'
/**
* Tenant Roles for Care Home Staff:
* - admin: Full access within their care home(s)
* - caregiver: Can create/manage meal orders for residents
* - kitchen: Can view orders and mark as prepared
*/
const defaultTenantArrayField = tenantsArrayField({
tenantsArrayFieldName: 'tenants',
tenantsArrayTenantFieldName: 'tenant',
tenantsCollectionSlug: 'tenants',
arrayFieldAccess: {},
tenantFieldAccess: {},
rowFields: [
{
name: 'roles',
type: 'select',
defaultValue: ['caregiver'],
hasMany: true,
options: [
{ label: 'Admin', value: 'admin' },
{ label: 'Caregiver', value: 'caregiver' },
{ label: 'Kitchen', value: 'kitchen' },
],
required: true,
admin: {
description: 'Role(s) for this user within the care home',
},
access: {
update: ({ req }) => {
const { user } = req
if (!user) {
return false
}
// Super admins and tenant admins can update roles
return isSuperAdmin(user) || true
},
},
},
],
})
/**
* Users Collection
*
* Two-level role system:
* - Global roles: super-admin (system-wide access), user (access via tenant roles)
* - Tenant roles: admin, caregiver, kitchen (per care home)
*/
const Users: CollectionConfig = {
slug: 'users',
access: {
create: createAccess,
delete: updateAndDeleteAccess,
read: readAccess,
update: updateAndDeleteAccess,
},
admin: {
useAsTitle: 'email',
defaultColumns: ['email', 'roles', 'createdAt'],
},
auth: true,
endpoints: [externalUsersLogin],
fields: [
{
name: 'name',
type: 'text',
admin: {
description: 'Full name of the user',
},
},
{
type: 'text',
name: 'password',
hidden: true,
access: {
read: () => false,
update: ({ req, id }) => {
const { user } = req
if (!user) {
return false
}
if (id === user.id) {
return true
}
return isSuperAdmin(user)
},
},
},
{
admin: {
position: 'sidebar',
description: 'Global system role',
},
name: 'roles',
type: 'select',
defaultValue: ['user'],
hasMany: true,
options: [
{ label: 'Super Admin', value: 'super-admin' },
{ label: 'User', value: 'user' },
],
access: {
update: ({ req }) => {
return isSuperAdmin(req.user)
},
},
},
{
name: 'username',
type: 'text',
hooks: {
beforeValidate: [ensureUniqueUsername],
},
index: true,
},
{
...defaultTenantArrayField,
admin: {
...(defaultTenantArrayField?.admin || {}),
position: 'sidebar',
description: 'Care homes this user has access to',
},
},
],
hooks: {
afterLogin: [setCookieBasedOnDomain],
},
}
export default Users