Getting started

Vector adds an admin to an existing Kinetis application that uses kinetis/orm. This page takes you from install to a working admin: the package, its tables, the three things your application provides, a first resource, and the UI.

Install

composer require kinetis/vector
vendor/bin/kinetis vector:install
vendor/bin/kinetis migrate

vector:install publishes Vector’s migrations — settings, preferences, saved views, the action log, the audit trail, jobs and notifications — for MySQL or PostgreSQL, as your connection’s DB_CONNECTION says (mysql or pgsql). There is one migration per table, each under its own timestamp: vector_settings, vector_preferences, vector_views, vector_action_events, vector_audit, vector_jobs and vector_notifications. It also copies the hosted UI bundle a released package ships into public/vector/ui; an install from source has none, and the command says so and still succeeds (Deployment). It is idempotent. A later change to Vector’s tables ships as a new migration with a later timestamp, so run it again after every upgrade, then migrate.

To keep Vector’s tables on a database of their own, see Databases.

Wire authentication

Authentication stays your application’s. Vector needs three things from it:

  1. Middleware in the vector group that registers the user. It authenticates the request your way (a JWT, a session) and puts a Kinetis\Http\CurrentUserInterface on the request scope. Add the vector-shell group for the hosted UI, and the mcp group if agents will use the MCP tools.

    #[AsMiddlewareGroup('vector', priority: 50)]
    #[AsMiddlewareGroup('vector-shell', priority: 50)]
    #[AsMiddlewareGroup('mcp', priority: 50)]
    final readonly class AdminAuthMiddleware implements MiddlewareInterface
    {
        // authenticate, then register CurrentUserInterface on the RequestScope
    }
    
  2. An access policy. VectorAccessInterface decides who may enter the admin at all. Bind it in bootstrap.php:

    use Kinetis\Vector\Auth\VectorAccessInterface;
    
    $app->instance(VectorAccessInterface::class, new AdminsOnly());
    
    final readonly class AdminsOnly implements VectorAccessInterface
    {
        public function canAccessVector(CurrentUserInterface $user): bool
        {
            return $user instanceof Staff && $user->isAdmin;
        }
    }
    
  3. An actor resolver, for background jobs. Jobs run as the admin who started them. ActorResolverInterface::resolve(string $actorId) rebuilds that user in the worker. Without it, Vector queues nothing (Background jobs).

Impersonation is optional and needs one more binding; see Audit trail and impersonation. Authentication covers both UI modes in detail.

Declare a resource

A resource is a class extending VectorResource with a #[Resource] attribute naming the entity. Anywhere under your application namespace is fine; it is discovered.

use Kinetis\Vector\Attributes\Resource;
use Kinetis\Vector\VectorResource;

#[Resource(entity: Product::class, group: 'Catalog', icon: 'mdi-package-variant', title: 'name')]
final class ProductResource extends VectorResource
{
}

An empty class derives every field from the entity’s ORM mapping. Once you want control, declare fields(); see Resources and Fields.

Vector compiles every resource into one descriptor at kinetis build, and on each boot in development. A mistake — a field that maps no property, a sort on a field without a column — fails the build with the class and field named.

Open the admin

Pick one of the two deployment modes; Deployment compares them.

Hosted. Your application serves the UI at /vector/ui behind its own session login. With the bundle published by vector:install, set where your login page is and open /vector/ui:

VECTOR_LOGIN_URL=/login
VECTOR_LOGOUT_URL=/logout

Standalone. The UI is a Nuxt application of its own that extends the @kinetis/vector-ui layer and calls your API with a bearer token:

pnpm add @kinetis/vector-ui nuxt vuetify vuetify-nuxt-module
// nuxt.config.ts
export default defineNuxtConfig({
    extends: ['@kinetis/vector-ui'],
    runtimeConfig: { public: { vector: { apiBase: 'https://api.example.com' } } },
})

Your API must then allow the UI’s origin through CorsMiddleware, and offer the POST /auth/login endpoint the sign-in page calls.

Try the demo

The Vector repository ships a complete demo: a shop on MySQL and a support desk on PostgreSQL, both admin modes, background jobs and a seeded catalog. From demo/:

cp backend/.env.example backend/.env    # then set JWT_SECRET
docker compose up --build -d
docker compose exec app vendor/bin/kinetis migrate
docker compose exec --user www-data app vendor/bin/kinetis demo:seed

Open http://localhost:3000 and sign in as admin@vector.local with the password password. The demo application covers the services, the hosted admin and the seed data.

See also