@samveys/admin

Version
1.0.3Nov 5, 2026
Install
pnpm add @samveys/admin

From packages/admin/README.md in the framework repository.

Server-rendered admin panel for ORM models. Every model you register gets list, show, create, edit and delete screens. Every route needs a signed-in user and is checked against the resource's policy before any data is read or written. A resource without a policy rule denies the action.

Peers: @samveys/core, @samveys/http, @samveys/orm, @samveys/auth, @samveys/security, @samveys/session. No runtime dependencies of its own, no client bundle.

Use

ts
import { admin, resource } from '@samveys/admin'

admin({
  path: '/admin',
  resources: [
    resource(Post, {
      columns: ['id', 'title', 'status'],
      fields: ['title', 'body', 'status', 'published'],
      sortable: ['title', 'id'],
      searchable: ['title'],
      enums: { status: ['draft', 'live'] },
      policy: definePolicy({ viewAny: isStaff, view: isStaff, create: isStaff, update: isStaff, delete: isAdmin }),
    }),
  ],
})

The panel runs behind the session, csrf and auth middleware, so register those plugins in the app.

Rules

  • Deny by default. Policy actions are viewAny, view, create, update, delete. A missing rule is a 403; no signed-in user is a 401.
  • Allow lists. Only columns are rendered and only fields can be written, even if more are posted.
  • Sort and paging. Sorting by a column outside sortable is ignored; the page size is capped at 100.
  • CSRF. Writes are POST with the CSRF token. Delete is POST only.
  • Audit. Each create, update and delete adds a row to samveys_admin_audit with the user, resource, record id and the changed field names, never values.
  • HTML. Every value is escaped. Inputs have labels and errors are linked with aria-describedby.