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

26 lines
1.0 KiB
Python

from __future__ import annotations
from sqlalchemy import Boolean, Integer, String, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column
from store.persistence.base_model import Base
class User(Base):
"""Application user table."""
__tablename__ = "users"
__table_args__ = (
UniqueConstraint("oauth_provider", "oauth_id", name="uq_users_oauth_identity"),
{"comment": "Application user table."},
)
id: Mapped[str] = mapped_column(String(64), primary_key=True, unique=True, index=True)
email: Mapped[str] = mapped_column(String(255), unique=True, index=True)
password_hash: Mapped[str | None] = mapped_column(String(255), default=None)
system_role: Mapped[str] = mapped_column(String(16), default="user", index=True)
oauth_provider: Mapped[str | None] = mapped_column(String(64), default=None)
oauth_id: Mapped[str | None] = mapped_column(String(255), default=None)
needs_setup: Mapped[bool] = mapped_column(Boolean, default=False)
token_version: Mapped[int] = mapped_column(Integer, default=0)