Merge SERVICE role into AGENT
Build & Push / Test (client) (push) Successful in 31s
Build & Push / Test (server) (push) Successful in 38s
Build & Push / Build Client (push) Successful in 1m17s
Build & Push / Build Server (push) Successful in 1m18s

Every AGENT now gets an auto-generated API key on creation, shown once
in a modal. AGENTs log in with password and authenticate to the API
with X-Api-Key. pre-push.sql defensively migrates any residual SERVICE
rows to AGENT before Prisma rewrites the enum. Goddard is no longer
baked into the seed — create agents via Admin → Users.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-18 22:44:32 -04:00
parent a9ba74f1af
commit d8785a964d
18 changed files with 73 additions and 130 deletions
+3 -7
View File
@@ -42,21 +42,18 @@ const ROLE_LABELS: Record<Role, string> = {
ADMIN: 'Admin',
AGENT: 'Agent',
USER: 'User',
SERVICE: 'Service',
};
const ROLE_BADGE: Record<Role, string> = {
ADMIN: 'bg-purple-500/20 text-purple-400 border-purple-500/30',
AGENT: 'bg-blue-500/20 text-blue-400 border-blue-500/30',
USER: 'bg-gray-500/20 text-gray-400 border-gray-500/30',
SERVICE: 'bg-orange-500/20 text-orange-400 border-orange-500/30',
};
const ROLE_DESCRIPTIONS: Record<Role, string> = {
ADMIN: 'Full access — manage users, CTI config, close and delete tickets',
AGENT: 'Manage tickets — create, update, assign, comment, change status',
AGENT: 'Manage tickets and automation — logs in with password and can authenticate via API key',
USER: 'Basic access — view tickets and add comments only',
SERVICE: 'Automation account — authenticates via API key, no password login',
};
export default function AdminUsers() {
@@ -227,7 +224,7 @@ export default function AdminUsers() {
<td className="px-5 py-3 text-gray-400">{u.email}</td>
<td className="px-5 py-3">
<div className="flex items-center justify-end gap-2">
{u.role === 'SERVICE' && (
{u.role === 'AGENT' && (
<button
onClick={() => setRotating(u)}
className="text-gray-600 hover:text-gray-300 transition-colors"
@@ -343,7 +340,7 @@ export default function AdminUsers() {
type="password"
value={form.password}
onChange={(e) => setForm((f) => ({ ...f, password: e.target.value }))}
required={modal === 'add' && form.role !== 'SERVICE'}
required={modal === 'add'}
className={inputClass}
placeholder={modal === 'edit' ? '••••••••' : ''}
/>
@@ -359,7 +356,6 @@ export default function AdminUsers() {
<option value="AGENT">Agent</option>
<option value="USER">User</option>
<option value="ADMIN">Admin</option>
<option value="SERVICE">Service</option>
</select>
<p className="mt-1.5 text-xs text-gray-500">{ROLE_DESCRIPTIONS[form.role]}</p>
</div>