94901fc30f
- Three-column layout: Sidebar + SourcePanel (views + searchable category tree) + main - DocumentSlideOver (480px right panel): inline editing, type picker, AI suggestion confirm/reject, categories combobox, tags editor, sharing section, raw text, re-analyse/delete actions - ManageCategoriesDialog: inline rename, delete with confirm, search filter - DocumentsPage rewrite: filter chip system, multi-file upload queue, drag-and-drop overlay, bulk actions bar (share/delete), smart TanStack Query polling, URL-driven view state - Sidebar simplified: per-category NavLinks removed; Documents = single NavLink under Apps - Backend: document_shares table (migration 0004), share CRUD endpoints, shared-with-me view, N+1-safe share_count via GROUP BY, recipient download access, X-User-Groups header enforcement - Gateway proxy: injects X-User-Groups header into all document + category proxy requests - Backend users: GET /api/users/me/groups endpoint for share picker combobox - CLAUDE.md, STATUS.md files, and changelog updated Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
24 lines
832 B
Python
24 lines
832 B
Python
import uuid
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import DateTime, String, UniqueConstraint, func
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.database import Base
|
|
|
|
|
|
class DocumentShare(Base):
|
|
__tablename__ = "document_shares"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
|
|
document_id: Mapped[str] = mapped_column(String, nullable=False, index=True)
|
|
group_id: Mapped[str] = mapped_column(String, nullable=False, index=True)
|
|
shared_by_user_id: Mapped[str] = mapped_column(String, nullable=False)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), server_default=func.now(), nullable=False
|
|
)
|
|
|
|
__table_args__ = (
|
|
UniqueConstraint("document_id", "group_id", name="uq_document_group_share"),
|
|
)
|