Pablan, as it stands

Self-hosted knowledge management for SMEs: a split-screen Markdown editor
whose sections an LLM refines while you write, and RAG question answering
over the documents that result. FastAPI + Postgres/pgvector on the back,
SvelteKit on the front, everything OpenAI-compatible and self-hostable.

Squashed into a single commit; the development history stays local.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CA43ZJda8Rbp2hKXNy8f6b
This commit is contained in:
ProfessorNova
2026-09-04 08:36:17 +02:00
co-authored by Claude Opus 5
commit 97dbff309c
346 changed files with 43430 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
"""Whose conversation this is.
A conversation is private to the user who started it — there is no sharing and
no admin view. One gate, used by every endpoint in the package, so the rule
cannot quietly differ between reading and writing.
"""
import uuid
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from app.errors import ApiError
from app.models import Conversation, User
async def own_conversation(
db: AsyncSession,
conversation_id: uuid.UUID,
user: User,
*,
with_messages: bool = False,
) -> Conversation:
stmt = select(Conversation).where(
Conversation.id == conversation_id, Conversation.user_id == user.id
)
if with_messages:
stmt = stmt.options(selectinload(Conversation.messages))
conversation = (await db.execute(stmt)).scalar_one_or_none()
if conversation is None:
# 404 rather than 403: someone else's conversation must not be
# confirmed to exist.
raise ApiError(404, "Conversation not found.", "not_found")
return conversation