forked from retoor/devplacepy
chore: document project-wide soft delete pattern and add deleted_by column to all tables
This commit is contained in:
@@ -66,6 +66,7 @@ devplacepy/
|
||||
| `/profile` | Profile view, editing, and a public **Media** tab (`?tab=media`) showing every attachment a user uploaded, newest first |
|
||||
| `/media` | Per-attachment soft delete and restore: `POST /media/{uid}/delete` (owner or admin), `POST /media/{uid}/restore` (admin) |
|
||||
| `/uploads` | File upload endpoints: `POST /uploads/upload` (multipart), `POST /uploads/upload-url` (from URL); served at `/static/uploads/` |
|
||||
| `/admin/trash` | Admin **Trash**: review, restore, and permanently purge soft-deleted content (posts, comments, gists, projects, news, project files, attachments) across the platform |
|
||||
| `/notifications` | Notification list, mark read, live unread counts (`/notifications/counts`) |
|
||||
| `/messages` | Direct messaging |
|
||||
| `/votes` | Upvote/downvote on posts, comments, projects |
|
||||
@@ -622,6 +623,10 @@ All indexes are created via `CREATE INDEX IF NOT EXISTS` wrapped in try/except -
|
||||
|
||||
SQLite is synchronous by design and will never be made async. It is more than fast enough for this platform: the database is a local file with WAL, a 30s busy timeout, and a 256MB memory map, so queries are sub-millisecond. The synchronous database layer is a deliberate architectural decision, not a limitation, and is not subject to change.
|
||||
|
||||
### Soft delete and data retention
|
||||
|
||||
Removing a record is a **soft delete**, not a physical one: it stamps `deleted_at` (timestamp) and `deleted_by` (actor) instead of erasing the row, and every list/count read filters `deleted_at IS NULL`, so the item disappears from the product while remaining recoverable. This covers user content (posts, comments, gists, projects, news, project files, attachments), engagement toggles (votes, reactions, bookmarks, follows, poll votes - which revive the same row when re-toggled), sessions (logout), container instances, and per-owner Devii/customization data. Deletions cascade with a shared timestamp so the whole event restores or purges as a unit. Garbage-collection operations (job retention, metrics ring buffers, usage-ledger pruning, expired-session cleanup) stay hard deletes - that is the stage that frees storage. Administrators review, restore, and permanently purge soft-deleted content from **Trash** at `/admin/trash`; the columns are indexed (`idx_<table>_deleted`).
|
||||
|
||||
## Testing
|
||||
|
||||
- **849+ tests** across 63 files: Playwright integration + in-process unit tests
|
||||
|
||||
Reference in New Issue
Block a user