This commit is contained in:
zuevav
2026-05-20 19:33:02 +03:00
commit f4bca8449e
30 changed files with 4152 additions and 0 deletions
+19
View File
@@ -0,0 +1,19 @@
{
"name": "@zbrain/shared",
"version": "0.1.0",
"private": true,
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": "./src/index.ts",
"./types": "./src/types.ts",
"./schemas": "./src/schemas.ts"
},
"scripts": {
"typecheck": "tsc --noEmit"
},
"dependencies": {
"zod": "^3.23.8"
}
}
+2
View File
@@ -0,0 +1,2 @@
export * from './types.js';
export * from './schemas.js';
+63
View File
@@ -0,0 +1,63 @@
import { z } from 'zod';
export const UserRoleSchema = z.enum(['owner', 'admin', 'editor', 'viewer']);
export const LoginRequestSchema = z.object({
email: z.string().email(),
password: z.string().min(8).max(256),
totpCode: z.string().regex(/^\d{6}$/).optional(),
});
export const CreateBrainSchema = z.object({
name: z.string().regex(/^[a-z0-9_]{1,32}$/, 'Только [a-z0-9_], до 32 символов'),
displayName: z.string().min(1).max(128),
description: z.string().max(1024).optional(),
});
export const MCPScopeSchema = z.string().regex(
/^mcp:(read|write|admin):[a-z0-9_*]{1,32}$/,
'Формат: mcp:<read|write|admin>:<brain-name>'
) as z.ZodType<`mcp:${'read' | 'write' | 'admin'}:${string}`>;
export const CreateTokenSchema = z.object({
name: z.string().min(1).max(128),
scopes: z.array(MCPScopeSchema).min(1).max(20),
ipAllowlist: z.array(z.string()).max(50).optional(),
expiresInDays: z.number().int().min(1).max(3650).nullable().optional(),
});
export const SourceConfigGitSchema = z.object({
type: z.literal('git'),
url: z.string().url(),
branch: z.string().default('main'),
subpath: z.string().optional(),
localPath: z.string(),
});
export const SourceConfigLocalDirSchema = z.object({
type: z.literal('local_dir'),
path: z.string(),
});
export const SourceConfigManualSchema = z.object({
type: z.literal('manual'),
});
export const SourceConfigSchema = z.discriminatedUnion('type', [
SourceConfigGitSchema,
SourceConfigLocalDirSchema,
SourceConfigManualSchema,
]);
export const CreateSourceSchema = z.object({
type: z.enum(['git', 'local_dir', 'manual']),
config: SourceConfigSchema,
schedule: z.string().nullable().optional(), // cron expression
});
export const CreateProjectSchema = z.object({
name: z.string().min(1).max(128),
slug: z.string().regex(/^[a-z0-9-]{1,64}$/, 'lowercase, цифры, дефисы'),
repoUrl: z.string().url().nullable().optional(),
description: z.string().max(1024).nullable().optional(),
});
+145
View File
@@ -0,0 +1,145 @@
// Shared types - используются и в API, и в Web
// Источник правды для контракта между frontend и backend
export type UserRole = 'owner' | 'admin' | 'editor' | 'viewer';
export interface User {
id: string;
email: string;
displayName: string | null;
role: UserRole;
oauthProvider: 'yandex' | 'github' | null;
totpEnabled: boolean;
createdAt: string;
lastLoginAt: string | null;
}
export interface Brain {
id: string;
name: string;
displayName: string;
description: string | null;
postgresDatabase: string;
mcpInternalPort: number;
ownerUserId: string;
createdAt: string;
// Computed stats
stats?: BrainStats;
}
export interface BrainStats {
pageCount: number;
chunkCount: number;
embeddedCount: number;
linkCount: number;
diskSizeMB: number;
lastSyncAt: string | null;
healthStatus: 'healthy' | 'warning' | 'critical';
embeddingCoverage: number; // 0..1
}
export type SourceType = 'git' | 'local_dir' | 'manual';
export interface Source {
id: string;
brainId: string;
type: SourceType;
config: SourceConfig;
schedule: string | null;
lastSyncAt: string | null;
lastSyncStatus: SyncStatus | null;
enabled: boolean;
}
export type SourceConfig =
| { type: 'git'; url: string; branch: string; subpath?: string; localPath: string }
| { type: 'local_dir'; path: string }
| { type: 'manual' };
export type SyncStatus = 'idle' | 'running' | 'success' | 'failed';
export type MCPScope = `mcp:${'read' | 'write' | 'admin'}:${string}`;
export interface AccessToken {
id: string;
name: string;
prefix: string;
createdByUserId: string;
scopes: MCPScope[];
ipAllowlist: string[] | null;
createdAt: string;
expiresAt: string | null;
lastUsedAt: string | null;
lastUsedIp: string | null;
revokedAt: string | null;
}
export interface CreateTokenRequest {
name: string;
scopes: MCPScope[];
ipAllowlist?: string[];
expiresInDays?: number; // null = no expiration
}
export interface CreateTokenResponse {
token: AccessToken;
plaintext: string; // показывается ОДИН РАЗ
}
export interface Project {
id: string;
name: string;
slug: string;
repoUrl: string | null;
description: string | null;
ownerUserId: string;
createdAt: string;
connections: ProjectConnection[];
}
export interface ProjectConnection {
brainId: string;
brainName: string;
brainDisplayName: string;
tokenId: string;
tokenName: string;
scope: 'read' | 'write';
}
export interface ConnectSnippet {
client: 'claude-code' | 'cursor' | 'cli';
language: string;
filename: string | null;
content: string;
description: string;
}
export interface AuditEntry {
id: number;
actorType: 'user' | 'token';
actorId: string;
actorName: string;
action: string;
resourceType: string | null;
resourceId: string | null;
payload: Record<string, unknown> | null;
ip: string | null;
userAgent: string | null;
createdAt: string;
}
// API responses
export interface PaginatedResponse<T> {
items: T[];
total: number;
page: number;
pageSize: number;
}
export interface ApiError {
error: string;
code: string;
details?: Record<string, unknown>;
}
+21
View File
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"lib": ["ES2022"],
"declaration": true,
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"skipLibCheck": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"isolatedModules": true,
"verbatimModuleSyntax": false,
"outDir": "dist",
"rootDir": "src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}