Files
FabledScribe/src/fabledassistant/services/note_versions.py
T
bvandeusen 9036dfd931 Note editor sidebar, full-doc assist, persistent drafts, version history
NoteEditorView: two-column sidebar layout (project/milestone/tags/assist
always visible), removed assist toggle button, InlineAssistPanel removed.

Writing assist: whole_doc mode rewrites entire document; DiffView.vue
replaces editor during review showing full-document diff. Scope dropdown
in sidebar switches between whole-document and section modes.

Persistent drafts: migration 0022 adds note_drafts (UNIQUE per note+user)
and note_versions (max 20, auto-pruned) tables. Draft saved after generation
completes, restored on editor mount, cleared on accept/reject. Version
snapshot created automatically whenever note body changes on save.

HistoryPanel.vue: version list + DiffView modal, restore button writes
body back to editor.

Config: OLLAMA_NUM_CTX default raised to 65536; assist num_predict now
tracks Config.OLLAMA_NUM_CTX instead of a hardcoded 4096.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 17:10:55 -05:00

52 lines
1.8 KiB
Python

from sqlalchemy import select, text
from fabledassistant.models import async_session
from fabledassistant.models.note_version import NoteVersion
MAX_VERSIONS = 20
async def create_version(user_id: int, note_id: int, body: str, title: str) -> NoteVersion:
async with async_session() as session:
version = NoteVersion(note_id=note_id, user_id=user_id, body=body, title=title)
session.add(version)
await session.commit()
await session.refresh(version)
# Prune versions beyond MAX_VERSIONS
await session.execute(
text("""
DELETE FROM note_versions
WHERE id IN (
SELECT id FROM note_versions
WHERE note_id = :note_id AND user_id = :user_id
ORDER BY created_at DESC
OFFSET :max_versions
)
""").bindparams(note_id=note_id, user_id=user_id, max_versions=MAX_VERSIONS)
)
await session.commit()
return version
async def list_versions(user_id: int, note_id: int) -> list[NoteVersion]:
async with async_session() as session:
result = await session.execute(
select(NoteVersion)
.where(NoteVersion.note_id == note_id, NoteVersion.user_id == user_id)
.order_by(NoteVersion.created_at.desc())
)
return list(result.scalars().all())
async def get_version(user_id: int, note_id: int, version_id: int) -> NoteVersion | None:
async with async_session() as session:
result = await session.execute(
select(NoteVersion).where(
NoteVersion.id == version_id,
NoteVersion.note_id == note_id,
NoteVersion.user_id == user_id,
)
)
return result.scalars().first()