LoVisual/backend
loki5512344 a597425e45
feat(backend): DELETE /avatars removes the row and the S3 object
Frontend "Remove avatar" needs a way to clear the current user's picture
without uploading a placeholder. Adds the missing route.

- S3Storage::delete wraps aws_sdk_s3 DeleteObject. MinIO's delete is
  idempotent for missing keys, so a stray miss is silent.
- repo::clear_avatar returns true when a row existed so the handler can decide
  whether to also try the S3 delete (skip for users without an avatar).
- handlers::delete is authenticated (GatewayIdentity) and always returns 204,
  matching how the frontend button should behave after a repeat click.
  S3 delete is best-effort: if MinIO is unreachable we already committed the
  DB row removal and log a warn — the object becomes orphaned but is not
  served, because serve() looks up keys via the DB, not by URL.
- Route registered on the existing avatar_routes Router.
- 3 tests: happy path (post-then-delete → count==0), idempotent no-op,
  401 without identity.
2026-10-12 22:42:50 +02:00
..
accounts-service feat(backend): DELETE /avatars removes the row and the S3 object 2026-10-12 22:42:50 +02:00
addons-registry feat(accounts): outgoing mail over SMTP (Resend), email verification, fail-closed password reset 2026-10-09 21:08:33 +02:00
chat-service build(backend): one shared Dockerfile with cargo cache mounts, sequential compose build, stripped release binaries 2026-10-09 22:01:09 +02:00
common feat(accounts): outgoing mail over SMTP (Resend), email verification, fail-closed password reset 2026-10-09 21:08:33 +02:00
configs-service build(backend): one shared Dockerfile with cargo cache mounts, sequential compose build, stripped release binaries 2026-10-09 22:01:09 +02:00
deploy deploy(nginx): serve the mod jar from nginx with a speed cap (750k per connection) and 2 connections per IP 2026-10-09 22:26:27 +02:00
gateway build(backend): one shared Dockerfile with cargo cache mounts, sequential compose build, stripped release binaries 2026-10-09 22:01:09 +02:00
scripts feat: GuiPresence (chat-service presence backend, gateway route, mod module); restore TODO history 2026-10-02 13:41:49 +02:00
.dockerignore chore(docker): keep the build context to the workspace crates 2026-09-29 18:46:46 +02:00
.env.example feat(accounts): outgoing mail over SMTP (Resend), email verification, fail-closed password reset 2026-10-09 21:08:33 +02:00
.gitignore chore(history): squash 59 commit(s) from 2026-09-23 2026-09-23 22:38:08 +02:00
Cargo.lock feat(accounts): outgoing mail over SMTP (Resend), email verification, fail-closed password reset 2026-10-09 21:08:33 +02:00
Cargo.toml build(backend): one shared Dockerfile with cargo cache mounts, sequential compose build, stripped release binaries 2026-10-09 22:01:09 +02:00
docker-compose.prod.yml build(backend): one shared Dockerfile with cargo cache mounts, sequential compose build, stripped release binaries 2026-10-09 22:01:09 +02:00
Dockerfile build(backend): one shared Dockerfile with cargo cache mounts, sequential compose build, stripped release binaries 2026-10-09 22:01:09 +02:00
PLAN.md chore(history): squash 100 commit(s) from 2026-09-24 2026-09-24 23:52:12 +02:00
STRUCTURE.md feat: GuiPresence (chat-service presence backend, gateway route, mod module); restore TODO history 2026-10-02 13:41:49 +02:00