feat(admin): Phase V2-6 Admin CRM 고도화 — CRUD + 차트 + 결제 + 감사
- DB: audit_log 테이블(diff 포함) + subscriptions.admin_note + super_admin role - Edge Functions 4개: admin-users, admin-subscriptions, admin-payments, admin-audit-log - 공유 유틸: admin-auth.ts(권한 검증), audit.ts(감사로그 기록) - Swagger UI: 독립 정적 페이지 + OpenAPI 3.0 spec - CRUD 페이지: 구독 생성/수정/삭제, role 변경, 감사로그 목록/상세 - recharts: feature별 StackedBar + DAU Line + Top Users HorizontalBar - 결제 이력: DB + Payple API 병행 조회 - 권한: super_admin만 위험 작업, admin은 조회 전용 - RLS: admin/super_admin IN 정책 + super_admin 쓰기 정책 - SQL RPC: admin_usage_by_feature, admin_top_users, admin_dau
This commit is contained in:
parent
f7c50eb2ed
commit
dca1b90faa
34 changed files with 3142 additions and 45 deletions
|
|
@ -9,6 +9,8 @@ import DashboardIcon from '@mui/icons-material/Dashboard'
|
|||
import PeopleIcon from '@mui/icons-material/People'
|
||||
import SubscriptionsIcon from '@mui/icons-material/Subscriptions'
|
||||
import BarChartIcon from '@mui/icons-material/BarChart'
|
||||
import HistoryIcon from '@mui/icons-material/History'
|
||||
import ApiIcon from '@mui/icons-material/Api'
|
||||
import LogoutIcon from '@mui/icons-material/Logout'
|
||||
import { PhosphorText } from '@d3ro/ui/components/ds'
|
||||
import { d3roPalette, d3roFontMono } from '@d3ro/ui/theme'
|
||||
|
|
@ -19,6 +21,11 @@ const NAV_ITEMS = [
|
|||
{ key: 'users', path: '/users', label: 'Users', icon: <PeopleIcon /> },
|
||||
{ key: 'subscriptions', path: '/subscriptions', label: 'Subscriptions', icon: <SubscriptionsIcon /> },
|
||||
{ key: 'usage', path: '/usage', label: 'Usage', icon: <BarChartIcon /> },
|
||||
{ key: 'audit-log', path: '/audit-log', label: 'Audit Log', icon: <HistoryIcon /> },
|
||||
]
|
||||
|
||||
const EXTERNAL_LINKS = [
|
||||
{ key: 'swagger', href: '/admin-swagger/', label: 'API Docs', icon: <ApiIcon /> },
|
||||
]
|
||||
|
||||
export function AdminSidebar(): React.ReactElement {
|
||||
|
|
@ -78,6 +85,41 @@ export function AdminSidebar(): React.ReactElement {
|
|||
</ListItem>
|
||||
)
|
||||
})}
|
||||
<ListItem disablePadding sx={{ mt: 1 }}>
|
||||
<ListItemText
|
||||
primary="EXTERNAL"
|
||||
primaryTypographyProps={{
|
||||
fontFamily: d3roFontMono,
|
||||
fontSize: 10,
|
||||
color: d3roPalette.text.label,
|
||||
px: 2,
|
||||
pt: 1,
|
||||
}}
|
||||
/>
|
||||
</ListItem>
|
||||
{EXTERNAL_LINKS.map((item) => (
|
||||
<ListItem key={item.key} disablePadding>
|
||||
<ListItemButton
|
||||
component="a"
|
||||
href={item.href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
sx={{ fontFamily: d3roFontMono }}
|
||||
>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: d3roPalette.text.inactive }}>
|
||||
{item.icon}
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary={item.label}
|
||||
primaryTypographyProps={{
|
||||
fontFamily: d3roFontMono,
|
||||
fontSize: 13,
|
||||
color: d3roPalette.text.secondary,
|
||||
}}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
|
||||
<Box sx={{ p: 2, borderTop: `1px solid ${d3roPalette.border.default}` }}>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue