feat: export Markdown notes (ARQ/Redis) + backup/restore BDD — v0.5.2
- Volume data/ (bind mount ./data) remplace le volume uploads nommé
data/notes/ → .md auto-générés, data/uploads/ → médias, data/backup/ → dumps
- Service Redis (redis:7-alpine) + worker ARQ (backend-worker)
- notes_markdown.py : frontmatter YAML + contenu + pièces jointes (liens relatifs)
Nom : YYYY-MM-DD_slug-titre_shortid.md, rotation si titre modifié
- api/notes.py : publie export_note_markdown / remove_note_markdown sur Redis
après chaque create / update / delete / add_attachment / delete_attachment
- api/admin.py : POST /backup, GET /backups, POST /restore/{filename} (pg_dump/pg_restore)
- Backend Dockerfile : postgresql-client ; requirements : arq==0.26.1
- ConfigPage : section "Base de données" avec sauvegarde + liste + restauration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
from app.core.database import get_session
|
||||
from app.core.redis import enqueue
|
||||
from app.models.notes import NoteItem, NoteAttachment
|
||||
from app.schemas.notes import NoteCreate, NoteUpdate, NoteResponse
|
||||
from app.services.media import save_image, save_audio, delete_media, ALLOWED_IMAGE_TYPES, ALLOWED_AUDIO_TYPES
|
||||
@@ -75,6 +76,7 @@ async def create_note(payload: NoteCreate, session: AsyncSession = Depends(get_s
|
||||
await session.refresh(note, ["attachments"])
|
||||
await session.commit()
|
||||
await session.refresh(note, ["attachments"])
|
||||
await enqueue("export_note_markdown", str(note.id))
|
||||
return note
|
||||
|
||||
|
||||
@@ -97,6 +99,7 @@ async def update_note(
|
||||
setattr(note, field, value)
|
||||
await session.commit()
|
||||
await session.refresh(note, ["attachments"])
|
||||
await enqueue("export_note_markdown", str(note.id))
|
||||
return note
|
||||
|
||||
|
||||
@@ -107,6 +110,7 @@ async def delete_note(note_id: uuid.UUID, session: AsyncSession = Depends(get_se
|
||||
raise HTTPException(404, "Note introuvable")
|
||||
await session.delete(note)
|
||||
await session.commit()
|
||||
await enqueue("remove_note_markdown", str(note_id))
|
||||
return Response(status_code=204)
|
||||
|
||||
|
||||
@@ -145,6 +149,7 @@ async def add_attachment(
|
||||
session.add(att)
|
||||
await session.commit()
|
||||
await session.refresh(note, ["attachments"])
|
||||
await enqueue("export_note_markdown", str(note_id))
|
||||
return note
|
||||
|
||||
|
||||
@@ -170,4 +175,5 @@ async def delete_attachment(
|
||||
)
|
||||
await session.delete(att)
|
||||
await session.commit()
|
||||
await enqueue("export_note_markdown", str(note_id))
|
||||
return Response(status_code=204)
|
||||
|
||||
Reference in New Issue
Block a user