초기 커밋

This commit is contained in:
2026-03-01 07:44:19 +09:00
commit 09359f30be
146 changed files with 6120 additions and 0 deletions

0
app/admin/__init__.py Normal file
View File

56
app/admin/setup.py Normal file
View File

@@ -0,0 +1,56 @@
from __future__ import annotations
from fastapi import FastAPI
from sqladmin import Admin
from sqladmin.authentication import AuthenticationBackend
from starlette.requests import Request
from app.core.config import settings
from app.core.constants import Role
from app.core.security import decode_token
from app.db.mariadb import async_engine
class AdminAuth(AuthenticationBackend):
async def login(self, request: Request) -> bool:
form = await request.form()
token = str(form.get("token", ""))
payload = decode_token(token)
if payload and payload.get("role") in Role.ADMIN_ROLES:
request.session["token"] = token
return True
return False
async def logout(self, request: Request) -> bool:
request.session.clear()
return True
async def authenticate(self, request: Request) -> bool:
token = request.session.get("token")
if not token:
return False
payload = decode_token(token)
return payload is not None and payload.get("role") in Role.ADMIN_ROLES
def setup_admin(app: FastAPI) -> Admin:
auth_backend = AdminAuth(secret_key=settings.SECRET_KEY)
admin = Admin(
app,
engine=async_engine,
authentication_backend=auth_backend,
title=f"{settings.APP_NAME} Admin",
)
from app.admin.views.device_admin import DeviceAdmin, DeviceGroupAdmin
from app.admin.views.system_admin import AuditLogAdmin, SystemConfigAdmin
from app.admin.views.user_admin import UserAdmin, UserProfileAdmin
admin.add_view(UserAdmin)
admin.add_view(UserProfileAdmin)
admin.add_view(DeviceAdmin)
admin.add_view(DeviceGroupAdmin)
admin.add_view(SystemConfigAdmin)
admin.add_view(AuditLogAdmin)
return admin

View File

View File

@@ -0,0 +1,32 @@
from __future__ import annotations
from sqladmin import ModelView
from app.models.mariadb.device import Device, DeviceGroup
class DeviceAdmin(ModelView, model=Device):
column_list = [
Device.id, Device.device_uid, Device.name, Device.device_type,
Device.status, Device.last_seen_at, Device.created_at,
]
column_searchable_list = [Device.device_uid, Device.name]
column_sortable_list = [Device.id, Device.name, Device.status, Device.created_at]
column_default_sort = ("id", True)
can_create = True
can_edit = True
can_delete = False
name = "Device"
name_plural = "Devices"
icon = "fa-solid fa-microchip"
class DeviceGroupAdmin(ModelView, model=DeviceGroup):
column_list = [DeviceGroup.id, DeviceGroup.name, DeviceGroup.description]
column_searchable_list = [DeviceGroup.name]
can_create = True
can_edit = True
can_delete = True
name = "Device Group"
name_plural = "Device Groups"
icon = "fa-solid fa-layer-group"

View File

@@ -0,0 +1,31 @@
from __future__ import annotations
from sqladmin import ModelView
from app.models.mariadb.system import AuditLog, SystemConfig
class SystemConfigAdmin(ModelView, model=SystemConfig):
column_list = [SystemConfig.id, SystemConfig.key, SystemConfig.value, SystemConfig.is_secret]
column_searchable_list = [SystemConfig.key]
can_create = True
can_edit = True
can_delete = True
name = "System Config"
name_plural = "System Configs"
icon = "fa-solid fa-gear"
class AuditLogAdmin(ModelView, model=AuditLog):
column_list = [
AuditLog.id, AuditLog.user_id, AuditLog.action,
AuditLog.resource_type, AuditLog.resource_id, AuditLog.created_at,
]
column_sortable_list = [AuditLog.id, AuditLog.created_at]
column_default_sort = ("id", True)
can_create = False
can_edit = False
can_delete = False
name = "Audit Log"
name_plural = "Audit Logs"
icon = "fa-solid fa-clipboard-list"

View File

@@ -0,0 +1,28 @@
from __future__ import annotations
from sqladmin import ModelView
from app.models.mariadb.user import User, UserProfile
class UserAdmin(ModelView, model=User):
column_list = [User.id, User.email, User.role, User.is_active, User.is_verified, User.created_at]
column_searchable_list = [User.email]
column_sortable_list = [User.id, User.email, User.created_at]
column_default_sort = ("id", True)
can_create = True
can_edit = True
can_delete = False
name = "User"
name_plural = "Users"
icon = "fa-solid fa-user"
class UserProfileAdmin(ModelView, model=UserProfile):
column_list = [UserProfile.id, UserProfile.user_id, UserProfile.full_name, UserProfile.organization]
column_searchable_list = [UserProfile.full_name]
can_create = False
can_delete = False
name = "User Profile"
name_plural = "User Profiles"
icon = "fa-solid fa-address-card"