cyi-box: Memphis-style toolbox admin platform

Go(fun)+SQLite backend, Vue 3 frontend. Modules: dashboard, pay gateway
(Epay-compatible + CDK stock), license/card system (per-app appid, domain
binding), AI memory bank with built-in MCP server (/mcp, FTS5 search,
signed read links), server SSH monitor + terminal + SFTP, proxy pool with
protocol-level alive checks, DB manager (mysql/pg/sqlite + SQL
autocomplete + import/export), disk share, vault (AES-GCM + TOTP),
bookmarks, dev tools.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
2026-10-01 01:58:47 +08:00
co-authored by Devin
commit 834ecacdb9
326 changed files with 27813 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
package db
import (
"context"
"database/sql"
)
type DBTX interface {
ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
PrepareContext(context.Context, string) (*sql.Stmt, error)
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
QueryRowContext(context.Context, string, ...interface{}) *sql.Row
}
func New(db DBTX) *Queries {
return &Queries{db: db}
}
type Queries struct {
db DBTX
}
func (q *Queries) WithTx(tx *sql.Tx) *Queries {
return &Queries{
db: tx,
}
}
+8
View File
@@ -0,0 +1,8 @@
// Package db sqlc 生成层。models.go / queries.sql.go 由 `go tool sqlc generate` 产出,
// 手写部分只有本文件——把 schema.sql 嵌进来供 store 运行时迁移。
package db
import _ "embed"
//go:embed schema.sql
var SchemaDDL string
+220
View File
@@ -0,0 +1,220 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
package db
type Bookmark struct {
ID int64
UserID int64
Title string
Url string
Icon string
Sort int64
CreatedAt int64
}
type Dbconn struct {
ID int64
Name string
Engine string
Host string
Port int64
Username string
PasswordEnc string
Database string
Params string
CreatedAt int64
UpdatedAt int64
}
type File struct {
ID int64
UserID int64
Name string
Stored string
Size int64
Mime string
CreatedAt int64
}
type LicenseApp struct {
ID int64
Appid string
Secret string
Name string
Enabled int64
CreatedAt int64
}
type LicenseCard struct {
ID int64
AppID int64
Card string
Hours int64
Domain string
ActivatedAt int64
ExpiresAt int64
CreatedAt int64
}
type Memory struct {
K string
Content string
Project string
Tags string
WrittenBy string
Revision int64
CreatedAt int64
UpdatedAt int64
}
type PayOrder struct {
ID int64
TradeNo string
OutTradeNo string
Channel string
Subject string
Money int64
Fee int64
Status int64
NotifyUrl string
ReturnUrl string
ClientIp string
Notified int64
NotifyAttempts int64
PaidAt int64
ExpiredAt int64
UpstreamTradeNo string
GoodsKey string
Quantity int64
UnitPrice int64
Payurl string
Qrcode string
BuyerContact string
QueryPwd string
Cards string
CreatedAt int64
}
type Proxy struct {
ID int64
Ip string
Port int64
Protocols string
Anonymity string
Source string
RegionID int64
Latency int64
Speed int64
Uptime int64
Alive int64
FailCount int64
LastCheckedAt int64
LastAliveAt int64
LastSeenAt int64
CreatedAt int64
}
type ProxyKey struct {
ID int64
Kkey string
Name string
RegionID int64
Enabled int64
UsedCount int64
LastUsedAt int64
CreatedAt int64
}
type ProxyRegion struct {
ID int64
Code string
Name string
ZhName string
Region string
Slug string
}
type ProxySync struct {
ID int64
StartedAt int64
FinishedAt int64
Status string
Source string
Total int64
Added int64
Removed int64
Updated int64
Detail string
Error string
}
type Server struct {
ID int64
Name string
Host string
Port int64
Username string
AuthType string
SecretEnc string
Note string
CreatedAt int64
UpdatedAt int64
}
type Session struct {
Token string
UserID int64
CreatedAt int64
ExpiresAt int64
}
type Setting struct {
K string
V string
}
type Share struct {
ID int64
Code string
FileID int64
UserID int64
FileName string
ExpiresAt int64
Downloads int64
CreatedAt int64
}
type Tool struct {
ID int64
Name string
Icon string
Url string
Description string
Sort int64
Enabled bool
}
type User struct {
ID int64
Name string
PasswordHash string
Role string
Status string
CreatedAt int64
UpdatedAt int64
}
type Vault struct {
ID int64
UserID int64
Title string
Username string
PasswordEnc string
Url string
Note string
TotpEnc string
CreatedAt int64
UpdatedAt int64
}
+136
View File
@@ -0,0 +1,136 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
package db
import (
"context"
"database/sql"
)
type Querier interface {
ActivateLicenseCard(ctx context.Context, arg ActivateLicenseCardParams) error
CountActiveSessions(ctx context.Context, expiresAt int64) (int64, error)
CountActiveUsers(ctx context.Context) (int64, error)
CountAdmins(ctx context.Context) (int64, error)
CountAllUsers(ctx context.Context) (int64, error)
CountBookmarksByUser(ctx context.Context, userID int64) (int64, error)
CountDbconns(ctx context.Context) (int64, error)
CountFilesAll(ctx context.Context) (int64, error)
CountLicenseApps(ctx context.Context) (int64, error)
CountLicenseCards(ctx context.Context, arg CountLicenseCardsParams) (int64, error)
CountMemories(ctx context.Context) (int64, error)
CountPayOrders(ctx context.Context, arg CountPayOrdersParams) (int64, error)
CountProxies(ctx context.Context) (int64, error)
CountProxiesAll(ctx context.Context) (int64, error)
CountProxiesFiltered(ctx context.Context, arg CountProxiesFilteredParams) (int64, error)
CountServers(ctx context.Context) (int64, error)
CountTodayLogins(ctx context.Context) (int64, error)
CountTools(ctx context.Context) (int64, error)
CountUsers(ctx context.Context, keyword sql.NullString) (int64, error)
CountVaultByUser(ctx context.Context, userID int64) (int64, error)
CreateLicenseApp(ctx context.Context, arg CreateLicenseAppParams) (int64, error)
CreateLicenseCard(ctx context.Context, arg CreateLicenseCardParams) error
CreatePayOrder(ctx context.Context, arg CreatePayOrderParams) (int64, error)
DeleteBookmark(ctx context.Context, arg DeleteBookmarkParams) (int64, error)
DeleteDbconn(ctx context.Context, id int64) (int64, error)
DeleteDeadProxies(ctx context.Context, lastCheckedAt int64) (int64, error)
DeleteFile(ctx context.Context, arg DeleteFileParams) (int64, error)
DeleteLicenseApp(ctx context.Context, id int64) error
DeleteLicenseCard(ctx context.Context, id int64) error
DeleteMemory(ctx context.Context, k string) (int64, error)
DeleteOtherSessions(ctx context.Context, arg DeleteOtherSessionsParams) error
DeleteProxy(ctx context.Context, id int64) error
DeleteProxyApiKey(ctx context.Context, id int64) (int64, error)
DeleteServer(ctx context.Context, id int64) (int64, error)
DeleteSession(ctx context.Context, token string) error
DeleteShare(ctx context.Context, arg DeleteShareParams) (int64, error)
DeleteSharesByFile(ctx context.Context, fileID int64) error
DeleteTool(ctx context.Context, id int64) error
DeleteUser(ctx context.Context, id int64) error
DeleteVault(ctx context.Context, arg DeleteVaultParams) (int64, error)
FinishProxySync(ctx context.Context, arg FinishProxySyncParams) error
GetDbconn(ctx context.Context, id int64) (Dbconn, error)
GetFile(ctx context.Context, id int64) (File, error)
GetLicenseAppByAppid(ctx context.Context, appid string) (LicenseApp, error)
GetLicenseCard(ctx context.Context, arg GetLicenseCardParams) (LicenseCard, error)
GetMemory(ctx context.Context, k string) (Memory, error)
GetPayOrder(ctx context.Context, id int64) (PayOrder, error)
GetPayOrderByOutNo(ctx context.Context, outTradeNo string) (PayOrder, error)
GetPayOrderByTradeNo(ctx context.Context, tradeNo string) (PayOrder, error)
GetProxyApiKey(ctx context.Context, kkey string) (ProxyKey, error)
GetProxyRegionByCode(ctx context.Context, code string) (ProxyRegion, error)
GetServer(ctx context.Context, id int64) (Server, error)
GetSessionUser(ctx context.Context, token string) (GetSessionUserRow, error)
GetSetting(ctx context.Context, k string) (string, error)
GetShareByCode(ctx context.Context, code string) (GetShareByCodeRow, error)
GetUserByID(ctx context.Context, id int64) (User, error)
GetUserByName(ctx context.Context, name string) (User, error)
GetVault(ctx context.Context, arg GetVaultParams) (Vault, error)
IncPayNotifyAttempts(ctx context.Context, id int64) error
IncShareDownloads(ctx context.Context, code string) error
InsertBookmark(ctx context.Context, arg InsertBookmarkParams) (int64, error)
InsertDbconn(ctx context.Context, arg InsertDbconnParams) (int64, error)
InsertFile(ctx context.Context, arg InsertFileParams) (int64, error)
InsertProxy(ctx context.Context, arg InsertProxyParams) (int64, error)
InsertProxyApiKey(ctx context.Context, arg InsertProxyApiKeyParams) (int64, error)
InsertProxySync(ctx context.Context, arg InsertProxySyncParams) (int64, error)
InsertServer(ctx context.Context, arg InsertServerParams) (int64, error)
InsertSession(ctx context.Context, arg InsertSessionParams) error
InsertShare(ctx context.Context, arg InsertShareParams) (int64, error)
InsertTool(ctx context.Context, arg InsertToolParams) (int64, error)
InsertUser(ctx context.Context, arg InsertUserParams) (int64, error)
InsertVault(ctx context.Context, arg InsertVaultParams) (int64, error)
LastProxyCheckAt(ctx context.Context) (interface{}, error)
LicenseCardStats(ctx context.Context, arg LicenseCardStatsParams) (LicenseCardStatsRow, error)
LicenseCardStatsAll(ctx context.Context, expiresAt int64) (LicenseCardStatsAllRow, error)
ListBookmarks(ctx context.Context, userID int64) ([]Bookmark, error)
ListDbconns(ctx context.Context) ([]Dbconn, error)
ListEnabledTools(ctx context.Context) ([]Tool, error)
ListFiles(ctx context.Context, userID int64) ([]File, error)
ListLicenseApps(ctx context.Context) ([]ListLicenseAppsRow, error)
ListLicenseCards(ctx context.Context, arg ListLicenseCardsParams) ([]LicenseCard, error)
ListMemories(ctx context.Context, arg ListMemoriesParams) ([]Memory, error)
ListPayOrders(ctx context.Context, arg ListPayOrdersParams) ([]PayOrder, error)
ListPendingPayOrders(ctx context.Context) ([]PayOrder, error)
ListProxiesDue(ctx context.Context, lastCheckedAt int64) ([]ListProxiesDueRow, error)
ListProxiesFiltered(ctx context.Context, arg ListProxiesFilteredParams) ([]ListProxiesFilteredRow, error)
ListProxyApiKeys(ctx context.Context) ([]ListProxyApiKeysRow, error)
ListProxyKeys(ctx context.Context) ([]ListProxyKeysRow, error)
ListProxyRegions(ctx context.Context) ([]ListProxyRegionsRow, error)
ListProxySyncs(ctx context.Context, limit int64) ([]ProxySync, error)
ListServers(ctx context.Context) ([]Server, error)
ListShares(ctx context.Context, userID int64) ([]Share, error)
ListTools(ctx context.Context) ([]Tool, error)
ListUsers(ctx context.Context, arg ListUsersParams) ([]User, error)
ListVault(ctx context.Context, arg ListVaultParams) ([]Vault, error)
LoginTrend(ctx context.Context, createdAt int64) ([]LoginTrendRow, error)
MarkProxyAlive(ctx context.Context, arg MarkProxyAliveParams) error
MarkProxyFailed(ctx context.Context, arg MarkProxyFailedParams) error
MemoryProjects(ctx context.Context) ([]MemoryProjectsRow, error)
PayDailyPaid(ctx context.Context, paidAt int64) ([]PayDailyPaidRow, error)
PayOrderStats(ctx context.Context, createdAt int64) (PayOrderStatsRow, error)
RandomProxies(ctx context.Context, arg RandomProxiesParams) ([]RandomProxiesRow, error)
RecentPaidOrders(ctx context.Context, limit int64) ([]RecentPaidOrdersRow, error)
SetPayNotified(ctx context.Context, id int64) error
SetPayOrderQrcode(ctx context.Context, arg SetPayOrderQrcodeParams) error
SetPayOrderStatus(ctx context.Context, arg SetPayOrderStatusParams) error
SetPayOrderUpstream(ctx context.Context, arg SetPayOrderUpstreamParams) error
TouchProxyApiKey(ctx context.Context, arg TouchProxyApiKeyParams) error
TouchSession(ctx context.Context, arg TouchSessionParams) error
UpdateBookmark(ctx context.Context, arg UpdateBookmarkParams) (int64, error)
UpdateDbconn(ctx context.Context, arg UpdateDbconnParams) (int64, error)
UpdateLicenseApp(ctx context.Context, arg UpdateLicenseAppParams) error
UpdateProxySeen(ctx context.Context, arg UpdateProxySeenParams) error
UpdateServer(ctx context.Context, arg UpdateServerParams) (int64, error)
UpdateTool(ctx context.Context, arg UpdateToolParams) error
UpdateUser(ctx context.Context, arg UpdateUserParams) error
UpdateUserPassword(ctx context.Context, arg UpdateUserPasswordParams) error
UpdateVault(ctx context.Context, arg UpdateVaultParams) (int64, error)
UpsertMemory(ctx context.Context, arg UpsertMemoryParams) error
UpsertProxyRegion(ctx context.Context, arg UpsertProxyRegionParams) error
UpsertSetting(ctx context.Context, arg UpsertSettingParams) error
}
var _ Querier = (*Queries)(nil)
+427
View File
@@ -0,0 +1,427 @@
-- name: GetUserByName :one
SELECT * FROM users WHERE name = ? LIMIT 1;
-- name: GetUserByID :one
SELECT * FROM users WHERE id = ?;
-- name: ListUsers :many
SELECT * FROM users
WHERE name LIKE '%' || sqlc.arg(keyword) || '%'
ORDER BY id LIMIT ? OFFSET ?;
-- name: CountUsers :one
SELECT COUNT(*) FROM users WHERE name LIKE '%' || sqlc.arg(keyword) || '%';
-- name: CountAllUsers :one
SELECT COUNT(*) FROM users;
-- name: CountActiveUsers :one
SELECT COUNT(*) FROM users WHERE status = 'active';
-- name: CountAdmins :one
SELECT COUNT(*) FROM users WHERE role = 'admin' AND status = 'active';
-- name: InsertUser :execlastid
INSERT INTO users(name, password_hash, role, status, created_at, updated_at)
VALUES(?, ?, ?, 'active', ?, ?);
-- name: UpdateUser :exec
UPDATE users SET name = ?, role = ?, status = ?, updated_at = ? WHERE id = ?;
-- name: UpdateUserPassword :exec
UPDATE users SET name = ?, role = ?, status = ?, password_hash = ?, updated_at = ? WHERE id = ?;
-- name: DeleteUser :exec
DELETE FROM users WHERE id = ?;
-- name: InsertSession :exec
INSERT INTO sessions(token, user_id, created_at, expires_at) VALUES(?, ?, ?, ?);
-- name: GetSessionUser :one
SELECT u.id, u.name, u.password_hash, u.role, u.status, u.created_at, u.updated_at, s.expires_at
FROM sessions s JOIN users u ON u.id = s.user_id WHERE s.token = ?;
-- name: DeleteSession :exec
DELETE FROM sessions WHERE token = ?;
-- name: DeleteOtherSessions :exec
DELETE FROM sessions WHERE user_id = ? AND token != ?;
-- name: TouchSession :exec
UPDATE sessions SET expires_at = ? WHERE token = ?;
-- name: CountActiveSessions :one
SELECT COUNT(*) FROM sessions WHERE expires_at > ?;
-- name: CountTodayLogins :one
SELECT COUNT(*) FROM sessions
WHERE date(created_at, 'unixepoch', 'localtime') = date('now', 'localtime');
-- name: LoginTrend :many
SELECT date(created_at, 'unixepoch', 'localtime') AS d, COUNT(*) AS c
FROM sessions WHERE created_at >= ? GROUP BY d;
-- name: ListTools :many
SELECT * FROM tools ORDER BY sort, id;
-- name: ListEnabledTools :many
SELECT * FROM tools WHERE enabled = 1 ORDER BY sort, id;
-- name: InsertTool :execlastid
INSERT INTO tools(name, icon, url, description, sort, enabled) VALUES(?, ?, ?, ?, ?, ?);
-- name: UpdateTool :exec
UPDATE tools SET name = ?, icon = ?, url = ?, description = ?, sort = ?, enabled = ? WHERE id = ?;
-- name: DeleteTool :exec
DELETE FROM tools WHERE id = ?;
-- name: CountTools :one
SELECT COUNT(*) FROM tools WHERE enabled = 1;
-- name: ListVault :many
SELECT * FROM vault WHERE user_id = ?
AND (title LIKE '%' || sqlc.arg(keyword) || '%'
OR username LIKE '%' || sqlc.arg(keyword) || '%'
OR url LIKE '%' || sqlc.arg(keyword) || '%')
ORDER BY updated_at DESC;
-- name: GetVault :one
SELECT * FROM vault WHERE user_id = ? AND id = ?;
-- name: InsertVault :execlastid
INSERT INTO vault(user_id, title, username, password_enc, url, note, totp_enc, created_at, updated_at)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?);
-- name: UpdateVault :execrows
UPDATE vault SET title = ?, username = ?, password_enc = ?, url = ?, note = ?, totp_enc = ?, updated_at = ?
WHERE id = ? AND user_id = ?;
-- name: DeleteVault :execrows
DELETE FROM vault WHERE user_id = ? AND id = ?;
-- name: ListBookmarks :many
SELECT * FROM bookmarks WHERE user_id = ? ORDER BY sort, id;
-- name: InsertBookmark :execlastid
INSERT INTO bookmarks(user_id, title, url, icon, sort, created_at) VALUES(?, ?, ?, ?, ?, ?);
-- name: UpdateBookmark :execrows
UPDATE bookmarks SET title = ?, url = ?, icon = ?, sort = ? WHERE id = ? AND user_id = ?;
-- name: DeleteBookmark :execrows
DELETE FROM bookmarks WHERE user_id = ? AND id = ?;
-- name: ListServers :many
SELECT * FROM servers ORDER BY id;
-- name: GetServer :one
SELECT * FROM servers WHERE id = ?;
-- name: InsertServer :execlastid
INSERT INTO servers(name, host, port, username, auth_type, secret_enc, note, created_at, updated_at)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?);
-- name: UpdateServer :execrows
UPDATE servers SET name = ?, host = ?, port = ?, username = ?, auth_type = ?, secret_enc = ?, note = ?, updated_at = ?
WHERE id = ?;
-- name: DeleteServer :execrows
DELETE FROM servers WHERE id = ?;
-- name: CountServers :one
SELECT COUNT(*) FROM servers;
-- name: ListDbconns :many
SELECT * FROM dbconns ORDER BY id;
-- name: GetDbconn :one
SELECT * FROM dbconns WHERE id = ?;
-- name: InsertDbconn :execlastid
INSERT INTO dbconns(name, engine, host, port, username, password_enc, database, params, created_at, updated_at)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
-- name: UpdateDbconn :execrows
UPDATE dbconns SET name = ?, engine = ?, host = ?, port = ?, username = ?, password_enc = ?, database = ?, params = ?, updated_at = ?
WHERE id = ?;
-- name: DeleteDbconn :execrows
DELETE FROM dbconns WHERE id = ?;
-- name: InsertFile :execlastid
INSERT INTO files(user_id, name, stored, size, mime, created_at) VALUES(?, ?, ?, ?, ?, ?);
-- name: ListFiles :many
SELECT * FROM files WHERE user_id = ? ORDER BY id DESC;
-- name: GetFile :one
SELECT * FROM files WHERE id = ?;
-- name: DeleteFile :execrows
DELETE FROM files WHERE id = ? AND user_id = ?;
-- name: InsertShare :execlastid
INSERT INTO shares(code, file_id, user_id, file_name, expires_at, created_at) VALUES(?, ?, ?, ?, ?, ?);
-- name: ListShares :many
SELECT * FROM shares WHERE user_id = ? ORDER BY id DESC;
-- name: GetShareByCode :one
SELECT sh.id, sh.code, sh.file_id, sh.user_id, sh.file_name, sh.expires_at, sh.downloads, sh.created_at,
f.name, f.stored, f.size, f.mime
FROM shares sh JOIN files f ON f.id = sh.file_id WHERE sh.code = ?;
-- name: DeleteShare :execrows
DELETE FROM shares WHERE id = ? AND user_id = ?;
-- name: DeleteSharesByFile :exec
DELETE FROM shares WHERE file_id = ?;
-- name: IncShareDownloads :exec
UPDATE shares SET downloads = downloads + 1 WHERE code = ?;
-- name: UpsertProxyRegion :exec
INSERT INTO proxy_regions(code, name, zh_name, region, slug) VALUES(?, ?, ?, ?, ?)
ON CONFLICT(code) DO UPDATE SET name = excluded.name, zh_name = excluded.zh_name,
region = excluded.region, slug = excluded.slug;
-- name: GetProxyRegionByCode :one
SELECT * FROM proxy_regions WHERE code = ?;
-- name: ListProxyRegions :many
SELECT r.*, (SELECT COUNT(*) FROM proxies p WHERE p.region_id = r.id AND p.alive = 1) AS alive_count
FROM proxy_regions r ORDER BY alive_count DESC, r.code;
-- name: ListProxyKeys :many
SELECT id, ip, port, source FROM proxies;
-- name: InsertProxy :execlastid
INSERT INTO proxies(ip, port, protocols, anonymity, source, region_id, latency, speed, uptime, alive, last_seen_at, created_at)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?);
-- name: UpdateProxySeen :exec
UPDATE proxies SET protocols = ?, anonymity = ?, region_id = ?, latency = ?, speed = ?, uptime = ?, last_seen_at = ?, alive = 1, fail_count = 0
WHERE id = ?;
-- name: DeleteProxy :exec
DELETE FROM proxies WHERE id = ?;
-- name: ListProxiesDue :many
SELECT id, ip, port, protocols, fail_count FROM proxies WHERE alive = 1 AND last_checked_at < ? ORDER BY last_checked_at LIMIT 20000;
-- name: MarkProxyAlive :exec
UPDATE proxies SET last_checked_at = ?, alive = 1, fail_count = 0, last_alive_at = ?, latency = ? WHERE id = ?;
-- name: MarkProxyFailed :exec
UPDATE proxies SET last_checked_at = ?, alive = 0, fail_count = ? WHERE id = ?;
-- name: DeleteDeadProxies :execrows
DELETE FROM proxies WHERE alive = 0 AND last_checked_at < ?;
-- name: CountProxies :one
SELECT COUNT(*) FROM proxies WHERE alive = 1;
-- name: CountProxiesFiltered :one
SELECT COUNT(*) FROM proxies p WHERE (? = 0 OR p.region_id = ?) AND (? = '' OR p.protocols LIKE '%' || ? || '%')
AND (? = '' OR p.ip LIKE '%' || ? || '%') AND (? < 0 OR p.alive = ?);
-- name: ListProxiesFiltered :many
SELECT p.*, r.code AS region_code, r.name AS region_name, r.zh_name AS region_zh_name
FROM proxies p JOIN proxy_regions r ON r.id = p.region_id
WHERE (? = 0 OR p.region_id = ?) AND (? = '' OR p.protocols LIKE '%' || ? || '%')
AND (? = '' OR p.ip LIKE '%' || ? || '%') AND (? < 0 OR p.alive = ?)
ORDER BY p.alive DESC, p.latency LIMIT ? OFFSET ?;
-- name: InsertProxySync :execlastid
INSERT INTO proxy_syncs(started_at, source) VALUES(?, ?);
-- name: FinishProxySync :exec
UPDATE proxy_syncs SET finished_at = ?, status = ?, total = ?, added = ?, removed = ?, updated = ?, detail = ?, error = ? WHERE id = ?;
-- name: ListProxySyncs :many
SELECT * FROM proxy_syncs ORDER BY id DESC LIMIT ?;
-- name: LastProxyCheckAt :one
SELECT COALESCE(MAX(last_checked_at), 0) FROM proxies;
-- name: InsertProxyApiKey :execlastid
INSERT INTO proxy_keys(kkey, name, region_id, created_at) VALUES(?, ?, ?, ?);
-- name: ListProxyApiKeys :many
SELECT k.*, r.code AS region_code, r.zh_name AS region_zh_name, r.name AS region_name
FROM proxy_keys k LEFT JOIN proxy_regions r ON r.id = k.region_id
ORDER BY k.id DESC;
-- name: GetProxyApiKey :one
SELECT * FROM proxy_keys WHERE kkey = ? AND enabled = 1;
-- name: TouchProxyApiKey :exec
UPDATE proxy_keys SET used_count = used_count + 1, last_used_at = ? WHERE id = ?;
-- name: DeleteProxyApiKey :execrows
DELETE FROM proxy_keys WHERE id = ?;
-- name: RandomProxies :many
SELECT p.id, p.ip, p.port, p.protocols, p.fail_count, r.code AS region_code, r.zh_name AS region_zh_name
FROM proxies p JOIN proxy_regions r ON r.id = p.region_id
WHERE p.alive = 1 AND (? = 0 OR p.region_id = ?) AND (? = '' OR p.protocols LIKE '%' || ? || '%')
AND (? = '' OR r.code = ?)
ORDER BY RANDOM() LIMIT ?;
-- name: GetSetting :one
SELECT v FROM settings WHERE k = ?;
-- name: UpsertSetting :exec
INSERT INTO settings (k, v) VALUES (?, ?) ON CONFLICT(k) DO UPDATE SET v = excluded.v;
-- name: CreatePayOrder :execlastid
INSERT INTO pay_orders (trade_no, out_trade_no, channel, subject, money, fee, notify_url, return_url, client_ip, expired_at, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
-- name: GetPayOrderByTradeNo :one
SELECT * FROM pay_orders WHERE trade_no = ?;
-- name: GetPayOrderByOutNo :one
SELECT * FROM pay_orders WHERE out_trade_no = ?;
-- name: SetPayOrderUpstream :exec
UPDATE pay_orders SET upstream_trade_no = ?, goods_key = ?, quantity = ?, unit_price = ?, payurl = ?, buyer_contact = ?, query_pwd = ? WHERE id = ?;
-- name: SetPayOrderQrcode :exec
UPDATE pay_orders SET qrcode = ? WHERE id = ?;
-- name: SetPayOrderStatus :exec
UPDATE pay_orders SET status = ?, paid_at = ?, cards = ? WHERE id = ?;
-- name: ListPendingPayOrders :many
SELECT * FROM pay_orders WHERE status = 0 AND upstream_trade_no != '' ORDER BY id LIMIT 200;
-- name: ListPayOrders :many
SELECT * FROM pay_orders
WHERE (? = -1 OR status = ?) AND (? = '' OR trade_no LIKE '%' || ? || '%' OR out_trade_no LIKE '%' || ? || '%')
ORDER BY id DESC LIMIT ? OFFSET ?;
-- name: CountPayOrders :one
SELECT COUNT(*) FROM pay_orders
WHERE (? = -1 OR status = ?) AND (? = '' OR trade_no LIKE '%' || ? || '%' OR out_trade_no LIKE '%' || ? || '%');
-- name: PayOrderStats :one
SELECT COUNT(*) AS cnt, COALESCE(SUM(CASE WHEN status = 1 THEN money ELSE 0 END), 0) AS money,
COALESCE(SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END), 0) AS pending,
COALESCE(SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END), 0) AS paid
FROM pay_orders WHERE created_at >= ?;
-- name: IncPayNotifyAttempts :exec
UPDATE pay_orders SET notify_attempts = notify_attempts + 1 WHERE id = ?;
-- name: SetPayNotified :exec
UPDATE pay_orders SET notified = 1 WHERE id = ?;
-- name: GetPayOrder :one
SELECT * FROM pay_orders WHERE id = ?;
-- name: CreateLicenseApp :execlastid
INSERT INTO license_apps (appid, secret, name, created_at) VALUES (?, ?, ?, ?);
-- name: GetLicenseAppByAppid :one
SELECT * FROM license_apps WHERE appid = ?;
-- name: ListLicenseApps :many
SELECT a.*, (SELECT COUNT(*) FROM license_cards c WHERE c.app_id = a.id) AS card_count
FROM license_apps a ORDER BY a.id DESC;
-- name: UpdateLicenseApp :exec
UPDATE license_apps SET name = ?, enabled = ? WHERE id = ?;
-- name: DeleteLicenseApp :exec
DELETE FROM license_apps WHERE id = ?;
-- name: CreateLicenseCard :exec
INSERT INTO license_cards (app_id, card, hours, created_at) VALUES (?, ?, ?, ?);
-- name: GetLicenseCard :one
SELECT * FROM license_cards WHERE app_id = ? AND card = ?;
-- name: ActivateLicenseCard :exec
UPDATE license_cards SET domain = ?, activated_at = ?, expires_at = ? WHERE id = ?;
-- name: ListLicenseCards :many
SELECT * FROM license_cards
WHERE app_id = ? AND (? = '' OR card LIKE '%' || ? || '%' OR domain LIKE '%' || ? || '%')
ORDER BY id DESC LIMIT ? OFFSET ?;
-- name: CountLicenseCards :one
SELECT COUNT(*) FROM license_cards
WHERE app_id = ? AND (? = '' OR card LIKE '%' || ? || '%' OR domain LIKE '%' || ? || '%');
-- name: LicenseCardStats :one
SELECT COUNT(*) AS total,
COALESCE(SUM(CASE WHEN activated_at = 0 THEN 1 ELSE 0 END), 0) AS unused,
COALESCE(SUM(CASE WHEN activated_at > 0 AND (expires_at = 0 OR expires_at > ?) THEN 1 ELSE 0 END), 0) AS active,
COALESCE(SUM(CASE WHEN activated_at > 0 AND expires_at > 0 AND expires_at <= ? THEN 1 ELSE 0 END), 0) AS expired
FROM license_cards WHERE app_id = ?;
-- name: DeleteLicenseCard :exec
DELETE FROM license_cards WHERE id = ?;
-- name: UpsertMemory :exec
INSERT INTO memories (k, content, project, tags, written_by, revision, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, 1, ?, ?)
ON CONFLICT(k) DO UPDATE SET
content = excluded.content,
project = excluded.project,
tags = excluded.tags,
written_by = excluded.written_by,
revision = memories.revision + 1,
updated_at = excluded.updated_at;
-- name: GetMemory :one
SELECT * FROM memories WHERE k = ?;
-- name: DeleteMemory :execrows
DELETE FROM memories WHERE k = ?;
-- name: ListMemories :many
SELECT * FROM memories
WHERE (? = '' OR project = ?) AND (? = '' OR tags LIKE '%"' || ? || '"%')
ORDER BY updated_at DESC LIMIT ?;
-- name: MemoryProjects :many
SELECT project AS name, COUNT(*) AS cnt FROM memories
WHERE project != '' GROUP BY project ORDER BY MAX(updated_at) DESC;
-- name: CountMemories :one
SELECT COUNT(*) FROM memories;
-- name: PayDailyPaid :many
SELECT CAST(strftime('%Y-%m-%d', paid_at, 'unixepoch', 'localtime') AS TEXT) AS day,
COALESCE(SUM(money), 0) AS money, COUNT(*) AS cnt
FROM pay_orders WHERE status = 1 AND paid_at >= ? GROUP BY day;
-- name: RecentPaidOrders :many
SELECT trade_no, subject, money, paid_at FROM pay_orders WHERE status = 1 ORDER BY paid_at DESC LIMIT ?;
-- name: LicenseCardStatsAll :one
SELECT COUNT(*) AS total,
COALESCE(SUM(CASE WHEN activated_at = 0 THEN 1 ELSE 0 END), 0) AS unused,
COALESCE(SUM(CASE WHEN activated_at > 0 AND (expires_at = 0 OR expires_at > ?) THEN 1 ELSE 0 END), 0) AS active
FROM license_cards;
-- name: CountLicenseApps :one
SELECT COUNT(*) FROM license_apps;
-- name: CountProxiesAll :one
SELECT COUNT(*) FROM proxies;
-- name: CountBookmarksByUser :one
SELECT COUNT(*) FROM bookmarks WHERE user_id = ?;
-- name: CountVaultByUser :one
SELECT COUNT(*) FROM vault WHERE user_id = ?;
-- name: CountDbconns :one
SELECT COUNT(*) FROM dbconns;
-- name: CountFilesAll :one
SELECT COUNT(*) FROM files;
File diff suppressed because it is too large Load Diff
+228
View File
@@ -0,0 +1,228 @@
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
role TEXT NOT NULL DEFAULT 'user',
status TEXT NOT NULL DEFAULT 'active',
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS sessions (
token TEXT PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
created_at INTEGER NOT NULL,
expires_at INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_sessions_user ON sessions(user_id);
CREATE INDEX IF NOT EXISTS idx_sessions_expiry ON sessions(expires_at);
CREATE TABLE IF NOT EXISTS tools (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
icon TEXT NOT NULL DEFAULT '',
url TEXT NOT NULL DEFAULT '',
description TEXT NOT NULL DEFAULT '',
sort INTEGER NOT NULL DEFAULT 0,
enabled INTEGER NOT NULL DEFAULT 1
);
CREATE TABLE IF NOT EXISTS vault (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
title TEXT NOT NULL,
username TEXT NOT NULL DEFAULT '',
password_enc TEXT NOT NULL DEFAULT '',
url TEXT NOT NULL DEFAULT '',
note TEXT NOT NULL DEFAULT '',
totp_enc TEXT NOT NULL DEFAULT '',
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_vault_user ON vault(user_id);
CREATE TABLE IF NOT EXISTS bookmarks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
title TEXT NOT NULL,
url TEXT NOT NULL,
icon TEXT NOT NULL DEFAULT '',
sort INTEGER NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_bookmarks_user ON bookmarks(user_id);
CREATE TABLE IF NOT EXISTS servers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
host TEXT NOT NULL,
port INTEGER NOT NULL DEFAULT 22,
username TEXT NOT NULL,
auth_type TEXT NOT NULL DEFAULT 'password',
secret_enc TEXT NOT NULL DEFAULT '',
note TEXT NOT NULL DEFAULT '',
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS files (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
name TEXT NOT NULL,
stored TEXT NOT NULL,
size INTEGER NOT NULL DEFAULT 0,
mime TEXT NOT NULL DEFAULT '',
created_at INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_files_user ON files(user_id);
CREATE TABLE IF NOT EXISTS shares (
id INTEGER PRIMARY KEY AUTOINCREMENT,
code TEXT NOT NULL UNIQUE,
file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
file_name TEXT NOT NULL DEFAULT '',
expires_at INTEGER NOT NULL DEFAULT 0,
downloads INTEGER NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_shares_user ON shares(user_id);
CREATE INDEX IF NOT EXISTS idx_shares_file ON shares(file_id);
CREATE TABLE IF NOT EXISTS dbconns (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
engine TEXT NOT NULL DEFAULT 'mysql',
host TEXT NOT NULL DEFAULT '',
port INTEGER NOT NULL DEFAULT 0,
username TEXT NOT NULL DEFAULT '',
password_enc TEXT NOT NULL DEFAULT '',
database TEXT NOT NULL DEFAULT '',
params TEXT NOT NULL DEFAULT '',
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS proxy_regions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
code TEXT NOT NULL UNIQUE,
name TEXT NOT NULL DEFAULT '',
zh_name TEXT NOT NULL DEFAULT '',
region TEXT NOT NULL DEFAULT '',
slug TEXT NOT NULL DEFAULT ''
);
CREATE TABLE IF NOT EXISTS proxies (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ip TEXT NOT NULL,
port INTEGER NOT NULL,
protocols TEXT NOT NULL DEFAULT '',
anonymity TEXT NOT NULL DEFAULT '',
source TEXT NOT NULL DEFAULT '',
region_id INTEGER NOT NULL REFERENCES proxy_regions(id) ON DELETE CASCADE,
latency INTEGER NOT NULL DEFAULT 0,
speed INTEGER NOT NULL DEFAULT 0,
uptime INTEGER NOT NULL DEFAULT 0,
alive INTEGER NOT NULL DEFAULT 1,
fail_count INTEGER NOT NULL DEFAULT 0,
last_checked_at INTEGER NOT NULL DEFAULT 0,
last_alive_at INTEGER NOT NULL DEFAULT 0,
last_seen_at INTEGER NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_proxies_addr ON proxies(ip, port);
CREATE INDEX IF NOT EXISTS idx_proxies_region ON proxies(region_id);
CREATE INDEX IF NOT EXISTS idx_proxies_alive ON proxies(alive);
CREATE INDEX IF NOT EXISTS idx_proxies_check ON proxies(alive, last_checked_at);
CREATE TABLE IF NOT EXISTS proxy_syncs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
started_at INTEGER NOT NULL,
finished_at INTEGER NOT NULL DEFAULT 0,
status TEXT NOT NULL DEFAULT '',
source TEXT NOT NULL DEFAULT '',
total INTEGER NOT NULL DEFAULT 0,
added INTEGER NOT NULL DEFAULT 0,
removed INTEGER NOT NULL DEFAULT 0,
updated INTEGER NOT NULL DEFAULT 0,
detail TEXT NOT NULL DEFAULT '',
error TEXT NOT NULL DEFAULT ''
);
CREATE TABLE IF NOT EXISTS proxy_keys (
id INTEGER PRIMARY KEY AUTOINCREMENT,
kkey TEXT NOT NULL UNIQUE,
name TEXT NOT NULL DEFAULT '',
region_id INTEGER NOT NULL DEFAULT 0,
enabled INTEGER NOT NULL DEFAULT 1,
used_count INTEGER NOT NULL DEFAULT 0,
last_used_at INTEGER NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS settings (
k TEXT PRIMARY KEY,
v TEXT NOT NULL DEFAULT ''
);
CREATE TABLE IF NOT EXISTS pay_orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
trade_no TEXT NOT NULL UNIQUE,
out_trade_no TEXT NOT NULL UNIQUE,
channel TEXT NOT NULL DEFAULT 'alipay',
subject TEXT NOT NULL DEFAULT '',
money INTEGER NOT NULL,
fee INTEGER NOT NULL DEFAULT 0,
status INTEGER NOT NULL DEFAULT 0, -- 0 待支付 1 已支付 3 已关闭
notify_url TEXT NOT NULL DEFAULT '',
return_url TEXT NOT NULL DEFAULT '',
client_ip TEXT NOT NULL DEFAULT '',
notified INTEGER NOT NULL DEFAULT 0,
notify_attempts INTEGER NOT NULL DEFAULT 0,
paid_at INTEGER NOT NULL DEFAULT 0,
expired_at INTEGER NOT NULL DEFAULT 0,
upstream_trade_no TEXT NOT NULL DEFAULT '',
goods_key TEXT NOT NULL DEFAULT '',
quantity INTEGER NOT NULL DEFAULT 0,
unit_price INTEGER NOT NULL DEFAULT 0,
payurl TEXT NOT NULL DEFAULT '',
qrcode TEXT NOT NULL DEFAULT '',
buyer_contact TEXT NOT NULL DEFAULT '',
query_pwd TEXT NOT NULL DEFAULT '',
cards TEXT NOT NULL DEFAULT '',
created_at INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_pay_orders_status ON pay_orders(status, created_at);
CREATE TABLE IF NOT EXISTS license_apps (
id INTEGER PRIMARY KEY AUTOINCREMENT,
appid TEXT NOT NULL UNIQUE,
secret TEXT NOT NULL,
name TEXT NOT NULL DEFAULT '',
enabled INTEGER NOT NULL DEFAULT 1,
created_at INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS license_cards (
id INTEGER PRIMARY KEY AUTOINCREMENT,
app_id INTEGER NOT NULL DEFAULT 0,
card TEXT NOT NULL UNIQUE,
hours INTEGER NOT NULL DEFAULT 24,
domain TEXT NOT NULL DEFAULT '',
activated_at INTEGER NOT NULL DEFAULT 0,
expires_at INTEGER NOT NULL DEFAULT 0,
created_at INTEGER NOT NULL
);
-- agent 共享记忆库:key 形态 "<project>/<topic>",跨会话/跨 agent 持久事实
CREATE TABLE IF NOT EXISTS memories (
k TEXT PRIMARY KEY,
content TEXT NOT NULL,
project TEXT NOT NULL DEFAULT '',
tags TEXT NOT NULL DEFAULT '[]',
written_by TEXT NOT NULL DEFAULT '',
revision INTEGER NOT NULL DEFAULT 1,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_memories_project ON memories(project, updated_at);