rayhpeng 0f82f8a3a2 feat(app): add plugin system with auth plugin and static assets
Add new application structure:
- app/main.py - application entry point
- app/plugins/ - plugin system with auth plugin:
  - api/ - REST API endpoints and schemas
  - authorization/ - auth policies, providers, hooks
  - domain/ - business logic (service, models, jwt, password)
  - injection/ - route injection and guards
  - ops/ - operational utilities
  - runtime/ - runtime configuration
  - security/ - middleware, CSRF, dependencies
  - storage/ - user repositories and models
- app/static/ - static assets (scalar.js for API docs)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-22 11:31:42 +08:00

56 lines
1.3 KiB
Python

from __future__ import annotations
from datetime import datetime
from typing import Protocol
from uuid import uuid4
from pydantic import BaseModel, ConfigDict, Field
def _new_user_id() -> str:
return str(uuid4())
class UserCreate(BaseModel):
model_config = ConfigDict(extra="forbid")
id: str = Field(default_factory=_new_user_id)
email: str
password_hash: str | None = None
system_role: str = "user"
oauth_provider: str | None = None
oauth_id: str | None = None
needs_setup: bool = False
token_version: int = 0
class User(BaseModel):
model_config = ConfigDict(frozen=True)
id: str
email: str
password_hash: str | None
system_role: str
oauth_provider: str | None
oauth_id: str | None
needs_setup: bool
token_version: int
created_time: datetime
updated_time: datetime | None
class UserRepositoryProtocol(Protocol):
async def create_user(self, data: UserCreate) -> User: ...
async def get_user_by_id(self, user_id: str) -> User | None: ...
async def get_user_by_email(self, email: str) -> User | None: ...
async def get_user_by_oauth(self, provider: str, oauth_id: str) -> User | None: ...
async def update_user(self, data: User) -> User: ...
async def count_users(self) -> int: ...
async def count_admin_users(self) -> int: ...