Initial miaojingAI project with image resolution guard
This commit is contained in:
67
audit_db_storage.js
Normal file
67
audit_db_storage.js
Normal file
@@ -0,0 +1,67 @@
|
||||
const { Client } = require('pg');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
require('dotenv').config({ path: '/root/miaojingAI/.env.local' });
|
||||
const c = new Client({ connectionString: process.env.LOCAL_DB_URL });
|
||||
const root = '/root/miaojingAI';
|
||||
function storageKeyFromUrl(url) {
|
||||
if (!url || typeof url !== 'string') return null;
|
||||
const marker = '/api/local-storage/';
|
||||
const idx = url.indexOf(marker);
|
||||
if (idx < 0) return null;
|
||||
try { return decodeURIComponent(url.slice(idx + marker.length).split('?')[0]); } catch { return null; }
|
||||
}
|
||||
async function query(name, sql, params=[]) {
|
||||
try { const r = await c.query(sql, params); return { name, rows: r.rows }; }
|
||||
catch (e) { return { name, error: e.message }; }
|
||||
}
|
||||
(async () => {
|
||||
await c.connect();
|
||||
const out = {};
|
||||
out.db = await query('db', `select current_database() as database, current_user as user, now() as checked_at`);
|
||||
out.tables = await query('tables', `select schemaname, tablename from pg_tables where schemaname in ('public','auth') order by schemaname, tablename`);
|
||||
const tableNames = out.tables.rows || [];
|
||||
out.counts = [];
|
||||
for (const t of tableNames) {
|
||||
const full = t.schemaname === 'public' ? t.tablename : `${t.schemaname}.${t.tablename}`;
|
||||
const r = await query(full, `select count(*)::int as count from ${full}`);
|
||||
out.counts.push({ table: full, count: r.rows?.[0]?.count ?? null, error: r.error });
|
||||
}
|
||||
out.admins = await query('admins', `select id,email,nickname,role,membership_tier,is_active,created_at,updated_at from profiles where role='admin' or email in ('admin@example.com','admin@miaojing.ai') order by created_at`);
|
||||
out.authAdmins = await query('auth_admins', `select id,email,created_at, password_hash is not null as has_password from auth.users where email in ('admin@example.com','admin@miaojing.ai') order by created_at`);
|
||||
out.profileWithoutAuth = await query('profile_without_auth', `select p.id,p.email,p.role from profiles p left join auth.users u on u.id=p.id where u.id is null order by p.created_at limit 50`);
|
||||
out.authWithoutProfile = await query('auth_without_profile', `select u.id,u.email from auth.users u left join profiles p on p.id=u.id where p.id is null order by u.created_at limit 50`);
|
||||
out.worksMissingUser = await query('works_missing_user', `select w.id,w.user_id,w.title,w.type,w.status,w.created_at from works w left join profiles p on p.id=w.user_id where w.user_id is not null and p.id is null order by w.created_at desc limit 50`);
|
||||
out.worksNullUser = await query('works_null_user', `select id,title,type,status,created_at from works where user_id is null order by created_at desc limit 50`);
|
||||
out.worksByStatus = await query('works_by_status', `select status, count(*)::int from works group by status order by status`);
|
||||
out.worksByUser = await query('works_by_user', `select p.email,p.nickname,w.user_id,count(*)::int as works from works w left join profiles p on p.id=w.user_id group by p.email,p.nickname,w.user_id order by works desc nulls last limit 20`);
|
||||
out.workLikesMissing = await query('work_likes_missing_refs', `select wl.id,wl.user_id,wl.work_id from work_likes wl left join profiles p on p.id=wl.user_id left join works w on w.id=wl.work_id where p.id is null or w.id is null limit 50`);
|
||||
out.creditMissingUser = await query('credit_missing_user', `select ct.id,ct.user_id,ct.amount,ct.type,ct.created_at from credit_transactions ct left join profiles p on p.id=ct.user_id where p.id is null limit 50`);
|
||||
out.ordersMissingUser = await query('orders_missing_user', `select o.id,o.user_id,o.order_no,o.status,o.created_at from orders o left join profiles p on p.id=o.user_id where o.user_id is not null and p.id is null limit 50`);
|
||||
out.apiKeysMissingUser = await query('api_keys_missing_user', `select k.id,k.user_id,k.provider,k.type from user_api_keys k left join profiles p on p.id=k.user_id where p.id is null limit 50`);
|
||||
out.jobsMissingUser = await query('jobs_missing_user', `select j.id,j.user_id,j.type,j.status,j.created_at from generation_jobs j left join profiles p on p.id=j.user_id where j.user_id is not null and p.id is null order by j.created_at desc limit 50`);
|
||||
out.jobsNullUser = await query('jobs_null_user', `select id,type,status,created_at from generation_jobs where user_id is null order by created_at desc limit 50`);
|
||||
out.jobsByUser = await query('jobs_by_user', `select p.email,p.nickname,j.user_id,count(*)::int as jobs from generation_jobs j left join profiles p on p.id=j.user_id group by p.email,p.nickname,j.user_id order by jobs desc nulls last limit 20`);
|
||||
out.worksFileCheck = { totalLocalUrls: 0, missing: [] };
|
||||
const works = await query('works_urls', `select id,result_url,thumbnail_url from works order by created_at desc`);
|
||||
for (const w of works.rows || []) {
|
||||
for (const field of ['result_url','thumbnail_url']) {
|
||||
const key = storageKeyFromUrl(w[field]);
|
||||
if (!key) continue;
|
||||
out.worksFileCheck.totalLocalUrls++;
|
||||
const abs = path.join(root, 'local-storage', key);
|
||||
if (!fs.existsSync(abs)) out.worksFileCheck.missing.push({ workId: w.id, field, key });
|
||||
}
|
||||
}
|
||||
out.storage = {
|
||||
localStorageExists: fs.existsSync(path.join(root,'local-storage')),
|
||||
backupsExists: fs.existsSync(path.join(root,'backups')),
|
||||
localFiles: 0,
|
||||
galleryFiles: 0,
|
||||
};
|
||||
function walk(dir) { if (!fs.existsSync(dir)) return 0; let n=0; for (const e of fs.readdirSync(dir,{withFileTypes:true})) { const p=path.join(dir,e.name); n += e.isDirectory()?walk(p):1; } return n; }
|
||||
out.storage.localFiles = walk(path.join(root,'local-storage'));
|
||||
out.storage.galleryFiles = walk(path.join(root,'local-storage','gallery'));
|
||||
console.log(JSON.stringify(out, null, 2));
|
||||
await c.end();
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
Reference in New Issue
Block a user