Files
task-team/api/src/routes/admin.js
Admin 42881b1f5a Add activity monitor, family workspace, per-user rate limiting
- Activity monitor API: phone usage tracking with report/summary/daily/ai-analysis endpoints
- Family workspace: shared task groups with member management
- Per-user API rate limiting: JWT-based key generator with IP fallback
- Also includes previously uncommitted spaced-repetition and admin routes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 00:54:38 +00:00

68 lines
3.1 KiB
JavaScript

// Task Team — Admin Dashboard — 2026-03-30
async function adminRoutes(app) {
// User management
app.get("/admin/users", async (req) => {
const { rows } = await app.db.query(
`SELECT u.id, u.email, u.name, u.phone, u.language, u.auth_provider, u.created_at,
(SELECT count(*) FROM tasks WHERE user_id=u.id) as task_count,
(SELECT count(*) FROM goals WHERE user_id=u.id) as goal_count
FROM users u ORDER BY u.created_at DESC`
);
return { data: rows };
});
app.delete("/admin/users/:id", async (req) => {
await app.db.query("DELETE FROM users WHERE id = $1", [req.params.id]);
return { status: "deleted" };
});
// System analytics
app.get("/admin/analytics", async (req) => {
const { rows: overview } = await app.db.query(`
SELECT
(SELECT count(*) FROM users) as total_users,
(SELECT count(*) FROM users WHERE created_at > NOW() - INTERVAL '7 days') as new_users_7d,
(SELECT count(*) FROM tasks) as total_tasks,
(SELECT count(*) FROM tasks WHERE status='completed' OR status='done') as completed_tasks,
(SELECT count(*) FROM tasks WHERE created_at > NOW() - INTERVAL '24 hours') as tasks_today,
(SELECT count(*) FROM goals) as total_goals,
(SELECT count(*) FROM invitations WHERE status='accepted') as accepted_invites,
(SELECT count(*) FROM task_comments WHERE is_ai=true) as ai_messages,
(SELECT count(*) FROM error_logs WHERE created_at > NOW() - INTERVAL '24 hours') as errors_24h,
(SELECT count(*) FROM projects) as total_projects
`);
// Daily activity (last 7 days)
const { rows: daily } = await app.db.query(`
SELECT date_trunc('day', created_at)::date as day, count(*) as tasks_created
FROM tasks WHERE created_at > NOW() - INTERVAL '7 days'
GROUP BY 1 ORDER BY 1
`);
return { data: { overview: overview[0], daily } };
});
// Recent activity feed
app.get("/admin/activity", async (req) => {
const { rows } = await app.db.query(`
(SELECT 'task_created' as type, title as detail, created_at FROM tasks ORDER BY created_at DESC LIMIT 5)
UNION ALL
(SELECT 'user_registered', email, created_at FROM users ORDER BY created_at DESC LIMIT 5)
UNION ALL
(SELECT 'goal_created', title, created_at FROM goals ORDER BY created_at DESC LIMIT 5)
UNION ALL
(SELECT 'invite_sent', invitee_email, created_at FROM invitations ORDER BY created_at DESC LIMIT 5)
ORDER BY created_at DESC LIMIT 20
`);
return { data: rows };
});
// Error log management
app.delete("/admin/errors/clear", async (req) => {
const { rowCount } = await app.db.query("DELETE FROM error_logs WHERE created_at < NOW() - INTERVAL '7 days'");
return { status: "cleared", deleted: rowCount };
});
}
module.exports = adminRoutes;