refactor gadget-code model interfaces to @gadget/api

Moved all Mongoose model interfaces to @gadget/api to commonize the data
structures being passed around the system as JSON objects via HTTP and
Socket.IO.
This commit is contained in:
Rob Colbert 2026-04-28 12:42:32 -04:00
parent 49d4290088
commit cc6d3b901a
25 changed files with 197 additions and 78 deletions

View File

@ -23,6 +23,7 @@
"dependencies": {
"@fortawesome/fontawesome-free": "^6.7.2",
"@gadget/ai": "workspace:*",
"@gadget/api": "workspace:*",
"ansicolor": "^2.0.3",
"bull": "^4.16.5",
"chart.js": "^4.5.0",

View File

@ -2,7 +2,14 @@
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
// All Rights Reserved
import { Schema, Document, model } from "mongoose";
import { Schema, model } from "mongoose";
import {
IAiModel,
IAiModelCapabilities,
IAiModelSettings,
IAiProvider,
} from "@gadget/api";
export const AiModelCapabilitiesSchema = new Schema<IAiModelCapabilities>(
{

View File

@ -3,6 +3,7 @@
// All Rights Reserved
import { Types, Schema, model } from "mongoose";
import { ChatSessionMode, IChatSession, IChatSessionPin } from "@gadget/api";
export const ChatSessionPinSchema = new Schema<IChatSessionPin>({
content: { type: String, required: true },

View File

@ -2,12 +2,16 @@
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
// All Rights Reserved
import { Types, Schema, Document, model } from "mongoose";
import { Types, Schema, model } from "mongoose";
import { IUser } from "./user.js";
import { IProject } from "./project.js";
import { ChatSessionMode, IChatSession } from "./chat-session.js";
import { IAiProvider } from "./ai-provider.js";
import {
ChatSessionMode,
ChatTurnStatus,
IChatSubagentProcess,
IChatToolCall,
IChatTurn,
IChatTurnStats,
} from "@gadget/api";
export const ChatTurnStatsSchema = new Schema<IChatTurnStats>({
toolCallCount: { type: Number, default: 0, required: true },

View File

@ -3,9 +3,9 @@
// All Rights Reserved
import { Schema, Types, model } from "mongoose";
import { IUser } from "./user.js";
import { DtpLog } from "../lib/log.js";
import { IUser } from "@gadget/api";
const log = new DtpLog({
name: "CsrfTokenModel",
slug: "csrfToken",

View File

@ -2,47 +2,14 @@
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
// All Rights Reserved
import { Types, Schema, Document, model } from "mongoose";
import { IDroneRegistration } from "./drone-registration";
import { Types, Schema, model } from "mongoose";
import { IDroneMonitor, IMemoryMonitor } from "@gadget/api";
/*
* Memory Monitor interface & schema
*/
export interface IMemoryMonitor {
count: number;
bytes: number;
}
export const MemoryMonitorSchema = new Schema<IMemoryMonitor>({
count: { type: Number, default: 0, required: true },
bytes: { type: Number, default: 0, required: true },
});
/*
* DroneMonitor interface & schema
*/
export interface IDroneMonitor extends Document {
_id: Types.ObjectId;
registration: IDroneRegistration | Types.ObjectId;
timestamp: Date;
memory: {
rss: number;
v8: {
heapTotal: number;
heapUsed: number;
heapExternal: number;
};
os: {
total: number;
free: number;
};
ai: {
subagents: IMemoryMonitor;
fileOperations: IMemoryMonitor;
toolCalls: IMemoryMonitor;
};
logs: IMemoryMonitor;
};
}
export const DroneMonitorSchema = new Schema<IDroneMonitor>({
registration: { type: Types.ObjectId, required: true, index: 1 },
timestamp: { type: Date, required: true, index: -1 },

View File

@ -2,25 +2,8 @@
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
// All Rights Reserved
import { Document, Schema, Types, model } from "mongoose";
import { IUser } from "./user";
export enum DroneStatus {
Starting = "starting",
Available = "available",
Busy = "busy",
Offline = "offline",
}
export interface IDroneRegistration extends Document {
_id: Types.ObjectId;
createdAt: Date;
updatedAt: Date;
user: IUser | Types.ObjectId;
hostname: string;
status: DroneStatus;
currentJobId?: string;
}
import { Schema, model } from "mongoose";
import { DroneStatus, IDroneRegistration } from "@gadget/api";
export const DroneRegistrationSchema = new Schema<IDroneRegistration>({
createdAt: { type: Date, required: true },

View File

@ -3,9 +3,9 @@
// All Rights Reserved
import { Schema, Types, model } from "mongoose";
import { IUser } from "@gadget/api";
import { DtpLog } from "../lib/log.js";
import { IUser } from "./user.js";
const log = new DtpLog({
name: "EmailVerificationModel",
slug: "emailVerification",
@ -37,7 +37,7 @@ export const EmailVerificationSchema = new Schema<IEmailVerification>({
export const EmailVerification = model<IEmailVerification>(
"EmailVerification",
EmailVerificationSchema
EmailVerificationSchema,
);
export default EmailVerification;

View File

@ -2,8 +2,9 @@
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
// All Rights Reserved
import { Types, Schema, Document, model } from "mongoose";
import { IUser } from "./user.js";
import { Types, Schema, model } from "mongoose";
import { IProject } from "@gadget/api";
export const ProjectSchema = new Schema<IProject>({
createdAt: { type: Date, default: Date.now, required: true },

View File

@ -2,9 +2,10 @@
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
// All Rights Reserved
import { Types, Schema, Document, model } from "mongoose";
import { Schema, model } from "mongoose";
import { DtpLog } from "../lib/log.js";
import { IUser, IUserFlags } from "@gadget/api";
const log = new DtpLog({
name: "UserModel",
slug: "user",

View File

@ -3,7 +3,8 @@
// All Rights Reserved
import { Schema, Types, model } from "mongoose";
import { IUser } from "./user.js";
import { IUser } from "@gadget/api";
import { DtpLog } from "../lib/log.js";
const log = new DtpLog({

View File

@ -5,7 +5,8 @@
import { Schema, Types, Document, model } from "mongoose";
import { DtpLog } from "../lib/log.js";
import { IUser } from "./user.js";
import { IUser } from "@gadget/api";
const log = new DtpLog({
name: "WebVisitModel",
slug: "webVisit",

View File

@ -21,6 +21,7 @@
"packageManager": "pnpm@10.33.2+sha512.a90faf6feeab71ad6c6e57f94e0fe1a12f5dcc22cd754db40ae9593eb6a3e0b6b12e3540218bb37ae083404b1f2ce6db2a4121e979829b4aff94b99f49da1cf8",
"dependencies": {
"@gadget/ai": "workspace:*",
"@gadget/api": "workspace:*",
"ansicolor": "^2.0.3",
"dayjs": "^1.11.20",
"dotenv": "^17.4.2",

1
packages/api/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
dist

28
packages/api/package.json Normal file
View File

@ -0,0 +1,28 @@
{
"name": "@gadget/api",
"version": "1.0.0",
"description": "Gadget Code API shared interfaces",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"scripts": {
"build": "tsc",
"dev": "tsc --watch"
},
"keywords": ["gadget", "api", "interfaces", "mongoose"],
"author": "Rob Colbert",
"license": "Apache-2.0",
"dependencies": {
"mongoose": "^8.16.1"
},
"devDependencies": {
"@types/node": "^25.6.0",
"typescript": "^6.0.3"
}
}

View File

@ -7,5 +7,8 @@ export * from "./interfaces/ai-provider.ts";
export * from "./interfaces/user.ts";
export * from "./interfaces/project.ts";
export * from "./interfaces/drone-registration.ts";
export * from "./interfaces/drone-monitor.ts";
export * from "./interfaces/chat-session.ts";
export * from "./interfaces/chat-turn.ts";

View File

@ -46,6 +46,8 @@ export interface IAiModel {
settings?: IAiModelSettings;
}
import { Document } from "mongoose";
export interface IAiProvider extends Document {
name: string;
apiType: AiApiType;

View File

@ -2,6 +2,10 @@
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
// Licensed under the Apache License, Version 2.0
import { Document, Types } from "mongoose";
import type { IUser } from "./user.js";
import type { IProject } from "./project.js";
export enum ChatSessionMode {
Plan = "plan", // for planning and brainstorming
Build = "build", // for building and coding

View File

@ -2,6 +2,13 @@
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
// Licensed under the Apache License, Version 2.0
import { Document, Types } from "mongoose";
import type { IUser } from "./user.js";
import type { IProject } from "./project.js";
import type { IChatSession } from "./chat-session.js";
import type { IAiProvider } from "./ai-provider.js";
import { ChatSessionMode } from "./chat-session.js";
export enum ChatTurnStatus {
Processing = "processing",
Finished = "finished",

View File

@ -0,0 +1,35 @@
// src/interfaces/drone-monitor.ts
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
// Licensed under the Apache License, Version 2.0
import { Types, Document } from "mongoose";
import { IDroneRegistration } from "./drone-registration.ts";
export interface IMemoryMonitor {
count: number;
bytes: number;
}
export interface IDroneMonitor extends Document {
_id: Types.ObjectId;
registration: IDroneRegistration | Types.ObjectId;
timestamp: Date;
memory: {
rss: number;
v8: {
heapTotal: number;
heapUsed: number;
heapExternal: number;
};
os: {
total: number;
free: number;
};
ai: {
subagents: IMemoryMonitor;
fileOperations: IMemoryMonitor;
toolCalls: IMemoryMonitor;
};
logs: IMemoryMonitor;
};
}

View File

@ -0,0 +1,23 @@
// src/interfaces/drone-registration.ts
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
// Licensed under the Apache License, Version 2.0
import { Types, Document } from "mongoose";
import { IUser } from "./user.ts";
export enum DroneStatus {
Starting = "starting",
Available = "available",
Busy = "busy",
Offline = "offline",
}
export interface IDroneRegistration extends Document {
_id: Types.ObjectId;
createdAt: Date;
updatedAt: Date;
user: IUser | Types.ObjectId;
hostname: string;
status: DroneStatus;
currentJobId?: string;
}

View File

@ -2,6 +2,9 @@
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
// Licensed under the Apache License, Version 2.0
import { Document, Types } from "mongoose";
import type { IUser } from "./user.js";
export interface IProject extends Document {
createdAt: Date;
user: IUser | Types.ObjectId;

View File

@ -9,6 +9,8 @@ export interface IUserFlags {
isBanned: boolean;
}
import { Document, Types } from "mongoose";
export interface IUser extends Document {
_id: Types.ObjectId;
email: string;

View File

@ -0,0 +1,24 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2022"],
"outDir": "./dist",
"rootDir": "./src",
"typeRoots": ["node_modules/@types", "types"],
"types": ["node"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"allowImportingTsExtensions": true,
"rewriteRelativeImportExtensions": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "src/**/*.test.ts"]
}

View File

@ -16,6 +16,9 @@ importers:
'@gadget/ai':
specifier: workspace:*
version: link:../packages/ai
'@gadget/api':
specifier: workspace:*
version: link:../packages/api
ansicolor:
specifier: ^2.0.3
version: 2.0.3
@ -239,6 +242,9 @@ importers:
'@gadget/ai':
specifier: workspace:*
version: link:../packages/ai
'@gadget/api':
specifier: workspace:*
version: link:../packages/api
ansicolor:
specifier: ^2.0.3
version: 2.0.3
@ -302,6 +308,19 @@ importers:
specifier: ^6.0.3
version: 6.0.3
packages/api:
dependencies:
mongoose:
specifier: ^8.16.1
version: 8.23.1
devDependencies:
'@types/node':
specifier: ^25.6.0
version: 25.6.0
typescript:
specifier: ^6.0.3
version: 6.0.3
packages:
'@adobe/css-tools@4.4.4':
@ -3690,7 +3709,7 @@ snapshots:
'@types/body-parser@1.19.6':
dependencies:
'@types/connect': 3.4.38
'@types/node': 24.12.2
'@types/node': 25.6.0
'@types/browser-sync@2.29.1':
dependencies:
@ -3711,7 +3730,7 @@ snapshots:
'@types/connect@3.4.38':
dependencies:
'@types/node': 24.12.2
'@types/node': 25.6.0
'@types/cookie-parser@1.4.10(@types/express@5.0.6)':
dependencies:
@ -3719,7 +3738,7 @@ snapshots:
'@types/cors@2.8.19':
dependencies:
'@types/node': 24.12.2
'@types/node': 25.6.0
'@types/deep-eql@4.0.2': {}
@ -3727,7 +3746,7 @@ snapshots:
'@types/express-serve-static-core@5.1.1':
dependencies:
'@types/node': 24.12.2
'@types/node': 25.6.0
'@types/qs': 6.15.0
'@types/range-parser': 1.2.7
'@types/send': 1.2.1
@ -3799,7 +3818,7 @@ snapshots:
'@types/send@1.2.1':
dependencies:
'@types/node': 24.12.2
'@types/node': 25.6.0
'@types/serve-favicon@2.5.7':
dependencies:
@ -3808,7 +3827,7 @@ snapshots:
'@types/serve-static@2.2.0':
dependencies:
'@types/http-errors': 2.0.5
'@types/node': 24.12.2
'@types/node': 25.6.0
'@types/uikit@3.23.0': {}
@ -3822,7 +3841,7 @@ snapshots:
'@types/ws@8.18.1':
dependencies:
'@types/node': 24.12.2
'@types/node': 25.6.0
'@vitejs/plugin-react@6.0.1(vite@8.0.10(@types/node@24.12.2)(esbuild@0.25.12)(jiti@2.6.1)(less@4.6.4)(tsx@4.21.0))':
dependencies:
@ -4334,7 +4353,7 @@ snapshots:
engine.io@6.6.7:
dependencies:
'@types/cors': 2.8.19
'@types/node': 24.12.2
'@types/node': 25.6.0
'@types/ws': 8.18.1
accepts: 1.3.8
base64id: 2.0.0