feat(ai): add @anthropic-ai/sdk, ai_usage table, ai.use permission
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
67
package-lock.json
generated
67
package-lock.json
generated
@@ -1,14 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "app-ts",
|
"name": "app-ts",
|
||||||
"version": "2.0.2",
|
"version": "2.0.8",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "app-ts",
|
"name": "app-ts",
|
||||||
"version": "2.0.2",
|
"version": "2.0.8",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@anthropic-ai/sdk": "^0.102.0",
|
||||||
"@dnd-kit/core": "^6.3.1",
|
"@dnd-kit/core": "^6.3.1",
|
||||||
"@dnd-kit/modifiers": "^9.0.0",
|
"@dnd-kit/modifiers": "^9.0.0",
|
||||||
"@dnd-kit/sortable": "^10.0.0",
|
"@dnd-kit/sortable": "^10.0.0",
|
||||||
@@ -71,6 +72,27 @@
|
|||||||
"vitest": "^4.1.0"
|
"vitest": "^4.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@anthropic-ai/sdk": {
|
||||||
|
"version": "0.102.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.102.0.tgz",
|
||||||
|
"integrity": "sha512-cThh3KcPW3lzkFyTz1cjyhJvOVw45NkLMoowO2ZJ/76CBz44ADUon+NsjEc/PypAkARs72Xu8qxTnx6PAOTQUQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"json-schema-to-ts": "^3.1.1",
|
||||||
|
"standardwebhooks": "^1.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"anthropic-ai-sdk": "bin/cli"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"zod": "^3.25.0 || ^4.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"zod": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@asamuzakjp/css-color": {
|
"node_modules/@asamuzakjp/css-color": {
|
||||||
"version": "5.1.11",
|
"version": "5.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.11.tgz",
|
||||||
@@ -2249,6 +2271,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@stablelib/base64": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@stablelib/base64/-/base64-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@standard-schema/spec": {
|
"node_modules/@standard-schema/spec": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
|
||||||
@@ -4073,6 +4101,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-sha256": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==",
|
||||||
|
"license": "Unlicense"
|
||||||
|
},
|
||||||
"node_modules/fast-uri": {
|
"node_modules/fast-uri": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
|
||||||
@@ -4801,6 +4835,19 @@
|
|||||||
"dequal": "^2.0.3"
|
"dequal": "^2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/json-schema-to-ts": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.18.3",
|
||||||
|
"ts-algebra": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/json-schema-traverse": {
|
"node_modules/json-schema-traverse": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||||
@@ -6751,6 +6798,16 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/standardwebhooks": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/standardwebhooks/-/standardwebhooks-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@stablelib/base64": "^1.0.0",
|
||||||
|
"fast-sha256": "^1.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/statuses": {
|
"node_modules/statuses": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||||
@@ -7139,6 +7196,12 @@
|
|||||||
"tree-kill": "cli.js"
|
"tree-kill": "cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ts-algebra": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "2.8.1",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"type": "commonjs",
|
"type": "commonjs",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@anthropic-ai/sdk": "^0.102.0",
|
||||||
"@dnd-kit/core": "^6.3.1",
|
"@dnd-kit/core": "^6.3.1",
|
||||||
"@dnd-kit/modifiers": "^9.0.0",
|
"@dnd-kit/modifiers": "^9.0.0",
|
||||||
"@dnd-kit/sortable": "^10.0.0",
|
"@dnd-kit/sortable": "^10.0.0",
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
-- AI assistant (Phase 1): usage-tracking table, monthly budget column, ai.use permission.
|
||||||
|
|
||||||
|
CREATE TABLE `ai_usage` (
|
||||||
|
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||||
|
`user_id` INTEGER NULL,
|
||||||
|
`kind` VARCHAR(20) NOT NULL,
|
||||||
|
`model` VARCHAR(50) NOT NULL,
|
||||||
|
`input_tokens` INTEGER NOT NULL DEFAULT 0,
|
||||||
|
`output_tokens` INTEGER NOT NULL DEFAULT 0,
|
||||||
|
`cost_usd` DECIMAL(10, 6) NOT NULL DEFAULT 0,
|
||||||
|
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
INDEX `idx_ai_usage_created` (`created_at`)
|
||||||
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `company_settings`
|
||||||
|
ADD COLUMN `ai_monthly_budget_usd` DECIMAL(10, 2) NULL DEFAULT 50.00;
|
||||||
|
|
||||||
|
-- ai.use permission + grant to admin (INSERT IGNORE → idempotent), mirroring
|
||||||
|
-- the warehouse-permissions migration.
|
||||||
|
INSERT IGNORE INTO `permissions` (`name`, `display_name`, `module`, `description`, `created_at`) VALUES
|
||||||
|
('ai.use', 'AI asistent', 'ai', 'Používat AI asistenta (chat a import faktur)', NOW());
|
||||||
|
|
||||||
|
INSERT IGNORE INTO `role_permissions` (`role_id`, `permission_id`)
|
||||||
|
SELECT r.id, p.id
|
||||||
|
FROM `roles` r
|
||||||
|
CROSS JOIN `permissions` p
|
||||||
|
WHERE r.name = 'admin'
|
||||||
|
AND p.name = 'ai.use';
|
||||||
@@ -76,6 +76,19 @@ model audit_logs {
|
|||||||
@@fulltext([description], map: "idx_audit_search")
|
@@fulltext([description], map: "idx_audit_search")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model ai_usage {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
user_id Int?
|
||||||
|
kind String @db.VarChar(20)
|
||||||
|
model String @db.VarChar(50)
|
||||||
|
input_tokens Int @default(0)
|
||||||
|
output_tokens Int @default(0)
|
||||||
|
cost_usd Decimal @default(0) @db.Decimal(10, 6)
|
||||||
|
created_at DateTime @default(now()) @db.Timestamp(0)
|
||||||
|
|
||||||
|
@@index([created_at], map: "idx_ai_usage_created")
|
||||||
|
}
|
||||||
|
|
||||||
model bank_accounts {
|
model bank_accounts {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
account_name String? @db.VarChar(255)
|
account_name String? @db.VarChar(255)
|
||||||
@@ -134,6 +147,7 @@ model company_settings {
|
|||||||
warehouse_issue_number_pattern String? @db.VarChar(100)
|
warehouse_issue_number_pattern String? @db.VarChar(100)
|
||||||
warehouse_inventory_prefix String? @db.VarChar(20)
|
warehouse_inventory_prefix String? @db.VarChar(20)
|
||||||
warehouse_inventory_number_pattern String? @db.VarChar(100)
|
warehouse_inventory_number_pattern String? @db.VarChar(100)
|
||||||
|
ai_monthly_budget_usd Decimal? @default(50.00) @db.Decimal(10, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
model customers {
|
model customers {
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ export const config = {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
anthropic: {
|
||||||
|
apiKey: process.env.ANTHROPIC_API_KEY || "",
|
||||||
|
},
|
||||||
|
|
||||||
nas: {
|
nas: {
|
||||||
path: process.env.NAS_PATH || "Z:/02_PROJEKTY",
|
path: process.env.NAS_PATH || "Z:/02_PROJEKTY",
|
||||||
financialsPath: process.env.NAS_FINANCIALS_PATH || "",
|
financialsPath: process.env.NAS_FINANCIALS_PATH || "",
|
||||||
|
|||||||
Reference in New Issue
Block a user