Skip to main content

Editing Companies

This guide covers how to view and update company details, including contact information, settings, and configuration options.


Overview​

What Can Be Edited?​

System Admins can update most company information:

CategoryEditable FieldsNon-Editable
IdentityNameSubdomain
ContactEmail, Phone-
AddressAddress, City, Postal Code-
BrandingLogo URL-
SettingsFull-Time HoursIndustry Template
StatusIs ActiveCreated At
Why Some Fields Are Locked

Subdomain and Industry Template are locked after creation because:

  • Subdomain affects URLs and authentication routing
  • Industry Template defines roles, rooms, and terminology
  • Changing these would break existing integrations

Accessing Company Details​

View Company​

  1. Navigate to Admin Portal
  2. Click Companies in the sidebar
  3. Click on a company name or View button
  4. Company details are displayed

Company Details API​

Endpoint: GET /api/companies/[companyId]

// Source: src/app/api/companies/[companyId]/route.ts:19-126
// Fetches company with related data
const { data } = await adminClient
.from('companies')
.select(`*,
industry_templates (*)`)
.eq('id', companyId)
.single()

// Also retrieves:
// - Staff count
// - Manager count
// - Opening hours

Response Structure​

// Company details response
{
success: true,
data: {
// Identity
id: "company-uuid",
name: "Example Practice",
subdomain: "example-practice",

// Contact
email: "contact@example.com",
phone: "+44 20 7946 0958",

// Address
address: "123 High Street",
city: "London",
postalCode: "SW1A 1AA",

// Settings
industryTemplateId: "template-uuid",
fullTimeHoursPerWeek: 37.5,
logoUrl: null,
isActive: true,

// Timestamps
createdAt: "2025-01-01T00:00:00Z",
updatedAt: "2025-01-14T10:30:00Z",

// Counts
staffCount: 15,
managerCount: 2,

// Related
industryTemplate: {
id: "template-uuid",
name: "gp_practice",
displayName: "GP Practice",
terminology: { /* ... */ }
},
openingHours: { /* ... */ }
}
}

Updating Company Information​

Update Company API​

Endpoint: PUT /api/companies/[companyId]

// Source: src/app/api/companies/[companyId]/route.ts:128-164
export async function PUT(request: NextRequest, { params }: RouteParams) {
// Requires System Admin role
if (getAuthRole(user) !== 'SYSTEM_ADMIN') {
return ApiResponses.forbidden('Forbidden - System Admin access required')
}

const body = await request.json()
const validationResult = parseWithErrors(updateCompanySchema, body)

if (!validationResult.success) {
return ApiResponses.badRequest('Validation failed', validationResult.errors)
}

const result = await companyDB.updateCompany(
companyId,
validationResult.data
)

return ApiResponses.success(result.data, { timing: result.timing.duration })
}

Validation Schema​

// Source: src/lib/validation/company.schemas.ts:97-116
export const updateCompanySchema = z.object({
name: z.string()
.min(2, 'Company name must be at least 2 characters')
.max(100, 'Company name must not exceed 100 characters')
.trim()
.optional(),
email: emailSchema.optional().nullable(),
phone: phoneSchema,
address: addressSchema,
city: citySchema,
postal_code: z.string()
.regex(postalCodeRegex, 'Invalid UK postal code format')
.optional()
.nullable(),
logo_url: z.string()
.url('Invalid logo URL')
.optional()
.nullable(),
is_active: z.boolean().optional()
})

Request Format​

// Update company request
const updateCompany = async (companyId: string, updates: CompanyUpdate) => {
const response = await fetch(`/api/companies/${companyId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(updates)
})

return response.json()
}

// Example usage
await updateCompany('company-uuid', {
name: 'Updated Practice Name',
email: 'newemail@practice.com',
phone: '+44 20 7946 1234',
address: '456 New Street',
city: 'Manchester',
postal_code: 'M1 1AA'
})

Editable Fields​

Company Name​

PropertyValue
Fieldname
TypeString
Min Length2 characters
Max Length100 characters
RequiredNo (for updates)
// Update company name
await updateCompany(companyId, {
name: 'New Practice Name'
})

Contact Information​

Email​

PropertyValue
Fieldemail
TypeString (email format)
Max Length255 characters
RequiredNo
// Update email
await updateCompany(companyId, {
email: 'contact@newdomain.com'
})

Phone​

PropertyValue
Fieldphone
TypeString
FormatInternational phone format
Max Length30 characters
RequiredNo
// Valid phone formats
'+44 20 7946 0958'
'020 7946 0958'
'+1 555 123 4567'

Address Fields​

Street Address​

PropertyValue
Fieldaddress
TypeString
Max Length200 characters
RequiredNo

City​

PropertyValue
Fieldcity
TypeString
Min Length2 characters
Max Length100 characters
RequiredNo

Postal Code​

PropertyValue
Fieldpostal_code
TypeString
FormatUK postal code
RequiredNo
// Valid UK postal codes
'SW1A 1AA'
'M1 1AA'
'EC1A 1BB'
'W1A 0AX'

Branding​

Logo URL​

PropertyValue
Fieldlogo_url
TypeString (URL)
RequiredNo
// Update logo
await updateCompany(companyId, {
logo_url: 'https://example.com/logo.png'
})

Database Schema​

Companies Table​

// Source: src/types/database.types.ts:262-320
companies: {
Row: {
address: string | null
city: string | null
created_at: string | null
email: string | null
full_time_hours_per_week: number | null
id: string
industry_template_id: string | null
is_active: boolean | null
logo_url: string | null
name: string
phone: string | null
postal_code: string | null
subdomain: string
updated_at: string | null
}
Update: {
address?: string | null
city?: string | null
email?: string | null
full_time_hours_per_week?: number | null
is_active?: boolean | null
logo_url?: string | null
name?: string
phone?: string | null
postal_code?: string | null
}
}

Update Workflow​

Step-by-Step Process​

1. Navigate to company details
2. Click "Edit Company" button
3. Modify desired fields
4. Review changes
5. Click "Save Changes"
6. Confirmation displayed

UI Components​

// Company edit form
const CompanyEditForm = ({ company, onSave }) => {
const [formData, setFormData] = useState({
name: company.name,
email: company.email || '',
phone: company.phone || '',
address: company.address || '',
city: company.city || '',
postal_code: company.postalCode || ''
})
const [saving, setSaving] = useState(false)

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setSaving(true)

try {
await onSave(formData)
// Show success toast
} catch (error) {
// Show error toast
} finally {
setSaving(false)
}
}

return (
<form onSubmit={handleSubmit} className="space-y-4">
{/* Form fields */}
<button type="submit" disabled={saving}>
{saving ? 'Saving...' : 'Save Changes'}
</button>
</form>
)
}

Validation Rules​

Field Validation​

FieldRules
Name2-100 chars, trimmed
EmailValid email format, max 255 chars
PhoneInternational format, max 30 chars
AddressMax 200 chars
City2-100 chars
Postal CodeUK format (e.g., SW1A 1AA)
Logo URLValid URL format

Validation Patterns​

// Source: src/lib/validation/company.schemas.ts:11-17
// Phone regex
const phoneRegex = /^\+?[1-9][\d\s\-().]{0,20}$/

// Postal code regex (UK format)
const postalCodeRegex = /^[A-Z]{1,2}\d[A-Z\d]?\s?\d[A-Z]{2}$/i

Error Handling​

// Validation error response
{
success: false,
error: "Validation failed",
details: {
name: ["Company name must be at least 2 characters"],
postal_code: ["Invalid UK postal code format"],
email: ["Invalid email format"]
}
}

Best Practices​

Do's and Don'ts​

DoDon't
Verify changes before savingMake changes without review
Keep contact info currentLeave outdated information
Use official company emailUse personal email addresses
Maintain accurate addressSkip address updates
Upload proper logo formatUse low-quality images

Update Considerations​

  1. Notify Company Manager - Inform of significant changes
  2. Verify Contact Details - Ensure accuracy of updates
  3. Update Consistently - Keep all records synchronised
  4. Document Changes - Note reason for updates

Audit Trail​

Change Logging​

All company updates are logged:

// Activity log entry
{
action: 'company_updated',
company_id: 'company-uuid',
manager_id: 'system-admin-uuid',
details: {
fields_updated: ['name', 'email'],
old_values: { name: 'Old Name', email: 'old@email.com' },
new_values: { name: 'New Name', email: 'new@email.com' }
},
created_at: '2025-01-14T10:30:00Z',
ip_address: '192.168.1.1'
}

Troubleshooting​

Common Issues​

IssueCauseSolution
Validation failedInvalid field formatCheck field requirements
Update failedNetwork errorRetry the operation
Forbidden errorInsufficient permissionsVerify System Admin role
Company not foundInvalid company IDCheck company exists

Error Messages​

ErrorMeaningAction
"Company name must be at least 2 characters"Name too shortUse longer name
"Invalid UK postal code format"Wrong postcodeUse format like SW1A 1AA
"Invalid email format"Bad emailCheck email syntax
"Forbidden - System Admin access required"Not authorisedLogin as System Admin


Source Files:

  • src/app/api/companies/[companyId]/route.ts - Company API endpoint
  • src/lib/validation/company.schemas.ts - Validation schemas
  • src/lib/db/company.ts - Database operations
  • src/types/database.types.ts - Database type definitions