Plugin Templates
Minimal Contract-Based Router
Section titled “Minimal Contract-Based Router”import { implement } from "@orpc/server";import { autoAuthMiddleware, type RpcContext } from "@checkstack/backend-api";import { myFeatureContract } from "@checkstack/my-feature-common";
const os = implement(myFeatureContract) .$context<RpcContext>() .use(autoAuthMiddleware);
export function createMyFeatureRouter({ database }) { return os.router({ getItems: os.getItems.handler(async () => { return await database.select().from(schema.items); }),
createItem: os.createItem.handler(async ({ input }) => { const [item] = await database.insert(schema.items).values(input).returning(); return item; }), });}Minimal oRPC Contract
Section titled “Minimal oRPC Contract”import { oc } from "@orpc/contract";import type { ProcedureMetadata } from "@checkstack/common";import { z } from "zod";import { myFeatureAccess } from "./access";
const _base = oc.$meta<ProcedureMetadata>({});
export const myFeatureContract = { getItems: _base .meta({ userType: "user", access: [myFeatureAccess.myfeatureRead] }) .output(z.array(ItemSchema)),
createItem: _base .meta({ userType: "user", access: [myFeatureAccess.myfeatureManage] }) .input(CreateItemSchema) .output(ItemSchema),};Minimal Access Rules
Section titled “Minimal Access Rules”import { accessPair } from "@checkstack/common";
/** * Access rules for my-feature plugin. * Uses accessPair() to create read/manage pairs. */export const myFeatureAccess = { ...accessPair("myfeature", { readDescription: "View items", manageDescription: "Create, update, delete items", isDefault: true, // read is auto-assigned to "users" role }),};
export const myFeatureAccessRules = Object.values(myFeatureAccess);Minimal Routes
Section titled “Minimal Routes”import { createRoutes } from "@checkstack/common";
export const myFeatureRoutes = createRoutes("my-feature", { home: "/",});Minimal Frontend Plugin
Section titled “Minimal Frontend Plugin”import { createFrontendPlugin, rpcApiRef, type ApiRef } from "@checkstack/frontend-api";import { myFeatureApiRef, type MyFeatureApiClient } from "./api";import { ItemsPage } from "./components/ItemsPage";import { myFeatureRoutes, MyFeatureApi, pluginMetadata, myFeatureAccess } from "@checkstack/my-feature-common";
export default createFrontendPlugin({ metadata: pluginMetadata,
routes: [ { route: myFeatureRoutes.routes.home, element: <ItemsPage />, title: "Items", accessRule: myFeatureAccess.myfeatureRead, }, ],
apis: [ { ref: myFeatureApiRef, factory: (deps: { get: <T>(ref: ApiRef<T>) => T }): MyFeatureApiClient => { const rpcApi = deps.get(rpcApiRef); return rpcApi.forPlugin(MyFeatureApi); }, }, ],});