45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
import {
|
|
pgTable,
|
|
uuid,
|
|
text,
|
|
integer,
|
|
timestamp,
|
|
jsonb,
|
|
index,
|
|
uniqueIndex,
|
|
} from "drizzle-orm/pg-core";
|
|
import type { PluginCategory, PluginStatus, PaperclipPluginManifestV1 } from "@paperclipai/shared";
|
|
|
|
/**
|
|
* `plugins` table — stores one row per installed plugin.
|
|
*
|
|
* Each plugin is uniquely identified by `plugin_key` (derived from
|
|
* the manifest `id`). The full manifest is persisted as JSONB in
|
|
* `manifest_json` so the host can reconstruct capability and UI
|
|
* slot information without loading the plugin package.
|
|
*
|
|
* @see PLUGIN_SPEC.md §21.3
|
|
*/
|
|
export const plugins = pgTable(
|
|
"plugins",
|
|
{
|
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
pluginKey: text("plugin_key").notNull(),
|
|
packageName: text("package_name").notNull(),
|
|
version: text("version").notNull(),
|
|
apiVersion: integer("api_version").notNull().default(1),
|
|
categories: jsonb("categories").$type<PluginCategory[]>().notNull().default([]),
|
|
manifestJson: jsonb("manifest_json").$type<PaperclipPluginManifestV1>().notNull(),
|
|
status: text("status").$type<PluginStatus>().notNull().default("installed"),
|
|
installOrder: integer("install_order"),
|
|
/** Resolved package path for local-path installs; used to find worker entrypoint. */
|
|
packagePath: text("package_path"),
|
|
lastError: text("last_error"),
|
|
installedAt: timestamp("installed_at", { withTimezone: true }).notNull().defaultNow(),
|
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
},
|
|
(table) => ({
|
|
pluginKeyIdx: uniqueIndex("plugins_plugin_key_idx").on(table.pluginKey),
|
|
statusIdx: index("plugins_status_idx").on(table.status),
|
|
}),
|
|
);
|