Files
kvitt/server/crates/kvitt-server/src/api/pictures.rs
T
jacobh2 06f48ef9e9 M2a: server workspace, kvitt-domain, skeleton routes, OpenAPI match, Dockerfile
Cargo workspace (kvitt-domain, kvitt-server, kvitt-import), Rust 1.99.1 pinned.
kvitt-domain passes every Rust vector and adds next_occurrence_date (D-015).
kvitt-server: config, SQLite pool (WAL, §8.9 pragmas), migration 0001 identical to
the contract schema, error type for all 25 codes, auth extractor and protocol
layer, all 33 routes (E-1/E-2 implemented, the rest 501), utoipa document equal
to contracts/openapi.yaml, seams for M3/M4/M9, serve/migrate/healthcheck.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 21:30:20 +02:00

65 lines
2.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Pictures: E-9 upload, E-10 remove, E-11 download (AC-4.4).
//!
//! Registered and annotated by M2a; M3 owns this file and implements the handlers (until then 501
//! `not_implemented`).
use crate::api::{IdPath, not_implemented};
use crate::auth::AuthDevice;
use crate::error::AppError;
use crate::openapi::responses::{
BadRequest, NotFound, PayloadTooLarge, Unprocessable, UnsupportedMediaType,
};
use crate::wire::{IntSchema, JpegBytes, PictureSizeSchema, PngBytes, User, UuidSchema, WebpBytes};
#[utoipa::path(
put,
path = "/me/picture",
operation_id = "putMePicture",
summary = "E-9 Upload own picture",
description = "JPEG, PNG or WebP up to 5 MiB and 8000 × 8000 px; processed per AC-4.4.",
request_body(content((JpegBytes = "image/jpeg"), (PngBytes = "image/png"), (WebpBytes = "image/webp"))),
responses(
(status = 200, description = "The user with the new `picture_version`.", body = User, content_type = "application/json; charset=utf-8"),
(status = 413, response = PayloadTooLarge),
(status = 415, response = UnsupportedMediaType),
(status = 422, response = Unprocessable),
)
)]
pub async fn put_me_picture(_device: AuthDevice) -> AppError {
not_implemented()
}
#[utoipa::path(
delete,
path = "/me/picture",
operation_id = "deleteMePicture",
summary = "E-10 Remove own picture",
description = "Idempotent.",
responses(
(status = 200, description = "The user with `picture_version` null.", body = User, content_type = "application/json; charset=utf-8"),
)
)]
pub async fn delete_me_picture(_device: AuthDevice) -> AppError {
not_implemented()
}
#[utoipa::path(
get,
path = "/users/{user_id}/picture",
operation_id = "getUserPicture",
summary = "E-11 Download a user's picture",
params(
("user_id" = UuidSchema, Path, description = "Not a UUID is 404 `not_found`."),
("size" = Option<PictureSizeSchema>, Query, description = "Other values are `invalid_request`."),
("v" = Option<IntSchema>, Query, description = "The `picture_version`; a cache key only, ignored by the server."),
),
responses(
(status = 200, description = "The square JPEG.", body = JpegBytes, content_type = "image/jpeg", headers(("ETag" = String, description = "`\"<picture_version>\"`"), ("Cache-Control" = String, description = "`private, max-age=31536000, immutable`"))),
(status = 400, response = BadRequest),
(status = 404, response = NotFound),
)
)]
pub async fn get_user_picture(_device: AuthDevice, IdPath(_user_id): IdPath) -> AppError {
not_implemented()
}