photoprism/internal/api
2026-05-23 21:35:26 +10:00
..
download Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02:00
embed UX: Refactor video formats and codecs in front and backend #1307 #3168 2025-01-28 23:26:52 +01:00
testdata AI: Finalize facial embeddings, labels and nsfw API endpoints #127 #1090 2025-04-10 20:28:26 +02:00
abort.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
AGENTS.md Docs: Split AGENTS guides into a hierarchical structure 2026-04-09 19:28:14 +02:00
albums.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
albums_search.go Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02:00
albums_search_test.go Config: Add "develop" feature flag to disable new viewer sidebar #3168 2025-02-03 12:29:02 +01:00
albums_test.go API: Extend pre-parse request limits to more JSON handlers 2026-03-08 10:29:34 +01:00
api.go API: Apply "golangci-lint" recommendations #5330 2025-11-22 09:25:01 +01:00
api_auth.go Logs: Improve log messages in API and share audit paths 2026-03-08 12:53:20 +01:00
api_auth_jwt.go Cluster: Improve usage of canonical terms in code/docs based on glossary 2026-02-23 16:16:29 +01:00
api_auth_jwt_test.go Cluster: Improve usage of canonical terms in code/docs based on glossary 2026-02-23 16:16:29 +01:00
api_auth_test.go merge: g-runewidth update, NewMinimalTestConfig updates, and ExamplesPath changed to SamplesPath 2026-03-10 14:47:23 +10:00
api_client_config.go API: Do not broadcast session-specific tokens via config.updated event 2026-03-09 11:09:17 +01:00
api_client_config_test.go API: Add config.updated broadcast tests to api_client_config_test.go 2026-05-10 15:07:37 +02:00
api_event.go Logs: Improve log messages in API and share audit paths 2026-03-08 12:53:20 +01:00
api_log.go Logs: Shorten the names of error log helper functions 2024-01-18 11:23:59 +01:00
api_methods.go API: Improve form and tests for POST /batch/photos/edit endpoint #271 2025-07-08 10:40:45 +02:00
api_request.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
api_response.go Auth: Use hashed auth tokens for enhanced security #3943 #808 #782 2024-01-06 17:35:19 +01:00
api_response_headers.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
api_response_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
api_test.go Merge remote-tracking branch 'origin/develop' into PostgreSQL 2026-02-11 18:05:34 +10:00
auth_tokens.go Security: Use individual preview tokens for each user account #98 2022-10-13 22:11:02 +02:00
batch_albums.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
batch_labels.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
batch_photos.go Merge remote-tracking branch 'origin/develop' into PostgreSQL 2026-03-10 13:32:02 +10:00
batch_photos_edit.go Events: Add photos.edited cache invalidation for batch edits #4966 2026-05-14 02:35:24 +00:00
batch_photos_edit_test.go Events: Add photos.edited cache invalidation for batch edits #4966 2026-05-14 02:35:24 +00:00
batch_photos_test.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
cache.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
cache_test.go Merge remote-tracking branch 'origin/develop' into PostgreSQL 2025-10-20 20:33:40 +10:00
cluster_health_test.go Security: Add gosec fixes with shared URL and fs validation helpers 2026-03-03 16:38:41 +01:00
cluster_metrics.go AI: Enhance "GET /api/v1/metrics" endpoint with additional stats #213 2025-10-31 15:38:10 +01:00
cluster_metrics_test.go Merge remote-tracking branch 'origin/develop' into PostgreSQL 2026-03-02 17:32:47 +10:00
cluster_nodes.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
cluster_nodes_redaction_test.go Config: Gate node roles by edition and align tests/lint 2026-02-26 15:37:55 +01:00
cluster_nodes_register.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
cluster_nodes_register_test.go API: Extend pre-parse request limits to more JSON handlers 2026-03-08 10:29:34 +01:00
cluster_nodes_test.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
cluster_nodes_update_siteurl_test.go Cluster: Revalidate portal proxy cache & tighten OAuth scope usage 2026-02-26 22:42:05 +01:00
cluster_permissions_test.go Cluster: Revalidate portal proxy cache & tighten OAuth scope usage 2026-02-26 22:42:05 +01:00
cluster_summary.go Cluster: Revalidate portal proxy cache & tighten OAuth scope usage 2026-02-26 22:42:05 +01:00
cluster_test_helpers.go Cluster: Protect register mutations and enforce CIDR gate 2026-02-26 19:59:33 +01:00
cluster_theme.go Logs: Replace status string literals with generic constants 2025-10-21 15:08:10 +02:00
cluster_theme_test.go Config: Gate node roles by edition and align tests/lint 2026-02-26 15:37:55 +01:00
config_options.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
config_options_test.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
config_settings.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
config_settings_test.go API: Extend pre-parse request limits to more JSON handlers 2026-03-08 10:29:34 +01:00
connect.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
connect_test.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
covers.go Config: Add an option to disable the web user interface #5111 2025-07-14 19:30:24 +02:00
covers_test.go API: Apply "golangci-lint" recommendations #5330 2025-11-22 09:25:01 +01:00
doc_overrides.go API: Add const, func, and struct comments for easier troubleshooting 2025-09-30 22:02:43 +02:00
docs.go Backend: Remove legacy Go build tags #5330 2025-11-22 09:24:28 +01:00
download.go API: Disable gzip compression for /api/v1/dl endpoint #127 #1090 2025-04-11 14:13:25 +02:00
download_album.go API: Apply "golangci-lint" recommendations #5330 2025-11-22 09:25:01 +01:00
download_album_test.go Tests: Add unit tests 2025-03-18 15:20:51 +01:00
download_test.go API: Disable gzip compression for /api/v1/dl endpoint #127 #1090 2025-04-11 14:13:25 +02:00
echo.go PWA: Improve service worker server endpoint #5274 2025-10-18 12:30:38 +02:00
echo_test.go CLI: Added JWT issuance and diagnostics sub commands #5230 2025-09-26 02:38:49 +02:00
errors.go API: Improve Swagger annotations and update swagger.json 2025-10-30 11:50:31 +01:00
errors_test.go API: Add additional fields to label and subject edit forms #383 #3168 2025-01-17 02:55:07 +01:00
faces.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
faces_search.go API: Improve logging of bad request errors across all endpoints #271 2025-07-10 09:38:36 +02:00
faces_search_test.go Config: Add "develop" feature flag to disable new viewer sidebar #3168 2025-02-03 12:29:02 +01:00
faces_test.go Auth: Refactor cluster configuration and provisioning API endpoints #98 2025-09-24 08:28:38 +02:00
file_delete.go API: Add "@Accept json" Swagger doc annotations where applicable 2025-01-19 15:26:18 +01:00
file_delete_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
file_orientation.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
files.go AI: Add vision package and vision API endpoints #127 #1090 2025-04-06 23:39:37 +02:00
files_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
folders_cover.go Config: Add an option to disable the web user interface #5111 2025-07-14 19:30:24 +02:00
folders_cover_test.go Auth: Refactor cluster configuration and provisioning API endpoints #98 2025-09-24 08:28:38 +02:00
folders_search.go Backend: Add security-focused tests, harden WebDAV and use safe.Download 2025-09-22 10:42:53 +02:00
folders_search_test.go Merge remote-tracking branch 'origin/develop' into PostgreSQL 2025-10-04 16:51:54 +10:00
health.go API: Add cluster operations endpoints to manage and register nodes #98 2025-09-15 06:43:43 +02:00
import.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
import_test.go Tests: Add unit tests 2025-03-12 16:34:28 +01:00
index.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
index_test.go API: Add additional fields to label and subject edit forms #383 #3168 2025-01-17 02:55:07 +01:00
labels.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
labels_search.go API: Fix incorrect Swagger response schemas and "Fore more" typos 2026-04-15 15:56:13 +02:00
labels_search_test.go API: Add additional fields to label and subject edit forms #383 #3168 2025-01-17 02:55:07 +01:00
labels_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
links.go API: Fix incorrect Swagger response schemas and "Fore more" typos 2026-04-15 15:56:13 +02:00
links_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
markers.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
markers_test.go Backend: Clean up error handling and unit tests in internal/ packages 2026-02-09 12:00:33 +01:00
mcp.go Backend: Compact verbose comments in config and MCP handler 2026-05-15 17:50:08 +00:00
mcp_test.go MCP: Add HTTP scope-gate tests for admin app password #5024 2026-05-10 15:00:43 +02:00
metrics.go Metrics: Use string constants in API endpoint #5355 2025-11-30 10:50:26 +01:00
metrics_test.go Config: Gate node roles by edition and align tests/lint 2026-02-26 15:37:55 +01:00
moments_time.go API: Fix incorrect Swagger response schemas and "Fore more" typos 2026-04-15 15:56:13 +02:00
moments_time_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
oauth_authorize.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
oauth_authorize_test.go Tests: Add unit tests 2024-07-16 17:26:18 +02:00
oauth_revoke.go API: Apply "golangci-lint" recommendations #5330 2025-11-22 09:25:01 +01:00
oauth_revoke_test.go API: Apply "golangci-lint" recommendations #5330 2025-11-22 09:25:01 +01:00
oauth_token.go API: Apply "golangci-lint" recommendations #5330 2025-11-22 09:25:01 +01:00
oauth_token_ratelimit_test.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
oauth_token_test.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
oauth_userinfo.go API: Add missing Swagger annotations and update swagger.json 2025-10-30 11:00:16 +01:00
oauth_userinfo_test.go Tests: Add unit tests 2024-07-16 17:26:18 +02:00
oidc_login.go API: Apply "golangci-lint" recommendations #5330 2025-11-22 09:25:01 +01:00
oidc_login_test.go Tests: Add unit tests 2024-07-17 16:35:49 +02:00
oidc_redirect.go OIDC: Merge groups, add inline code docs, and improve README.md #5334 2025-11-27 12:02:57 +01:00
oidc_redirect_test.go Frontend: Fix OIDC session restore and logout cleanup #5476 2026-03-08 14:27:39 +01:00
options.go API: Update swagger endpoint documentation #5133 2025-08-28 11:00:19 +02:00
photo_label.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
photo_label_test.go UX: Add batch edit dialog and API endpoints #271 #5324 2025-11-19 11:20:34 +01:00
photo_unstack.go Merge tag '251130-b3068414c' into PostgreSQL 2025-12-01 17:16:33 +10:00
photo_unstack_test.go Merge remote-tracking branch 'origin/develop' into PostgreSQL 2025-10-04 16:51:54 +10:00
photos.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
photos_search.go API: Fix incorrect Swagger response schemas and "Fore more" typos 2026-04-15 15:56:13 +02:00
photos_search_geo.go Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02:00
photos_search_geo_test.go Auth: Open album share links in the regular user interface #98 #782 2022-10-02 11:38:30 +02:00
photos_search_test.go API: Document "GET /api/v1/photos/view" in swagger.json 2026-04-15 14:01:19 +02:00
photos_test.go Auth: Refactor cluster configuration and provisioning API endpoints #98 2025-09-24 08:28:38 +02:00
places_reverse.go Places: Add config option to specify location details locale #465 #883 2025-07-03 12:58:20 +02:00
places_search.go Places: Add config option to specify location details locale #465 #883 2025-07-03 12:58:20 +02:00
places_test.go Tests: Add unit tests #465 2025-07-09 14:57:32 +02:00
reactions.go Auth: Add "node" and "portal" roles, refactor session entity #98 2025-09-18 13:33:18 +02:00
README.md Docs: Document NSFW flag gating and call-graph in package READMEs 2026-05-21 16:25:06 +02:00
request_limits.go MCP: Cap /api/v1/mcp body size and shorten session idle timeout #5024 2026-04-20 13:54:07 +02:00
server.go API: Apply "golangci-lint" recommendations #5330 2025-11-22 09:25:01 +01:00
services.go API: Fix incorrect Swagger response schemas and "Fore more" typos 2026-04-15 15:56:13 +02:00
services_search.go API: Improve logging of bad request errors across all endpoints #271 2025-07-10 09:38:36 +02:00
services_search_test.go API: Add additional fields to label and subject edit forms #383 #3168 2025-01-17 02:55:07 +01:00
services_test.go API: Update endpoints to return HTTP 201 when a new resource was created 2025-10-20 16:46:59 +02:00
services_upload.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
services_upload_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
session.go Backend: Move get package to /internal/photoprism/get 2024-07-02 08:03:30 +02:00
session_create.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
session_delete.go Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02:00
session_get.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
session_ratelimit_test.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
session_response.go Auth: Add "node" and "portal" roles, refactor session entity #98 2025-09-18 13:33:18 +02:00
session_test.go API: Enforce pre-parse body limits for login and uploads 2026-03-07 15:31:30 +01:00
share.go Config: Refactor frontend URI handling for configurable base paths 2026-02-25 00:55:16 +01:00
share_preview.go Clean-up: Drop imaging and pigo library integrations #5353 #5508 #668 2026-04-01 13:47:42 +02:00
share_preview_test.go Auth: Add CLI command to create access tokens for apps #782 #808 #3943 2024-01-05 16:31:07 +01:00
share_test.go API: Apply "golangci-lint" recommendations #5330 2025-11-22 09:25:01 +01:00
status.go API: Update swagger endpoint documentation #5133 2025-08-28 11:20:00 +02:00
status_test.go API: Add additional fields to label and subject edit forms #383 #3168 2025-01-17 02:55:07 +01:00
subjects.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
subjects_search.go API: Improve logging of bad request errors across all endpoints #271 2025-07-10 09:38:36 +02:00
subjects_search_test.go Config: Add "develop" feature flag to disable new viewer sidebar #3168 2025-02-03 12:29:02 +01:00
subjects_test.go UX: New Action Menu for Faces in People Editing Tab #4151 #797 #5249 2025-10-10 13:02:31 +02:00
svg.go API: Add missing Swagger annotations and update swagger.json 2025-10-30 11:00:16 +01:00
svg_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
swagger.json Config: Refactor flag default reporting and harden Markdown rendering 2026-05-09 15:09:54 +00:00
thumbnails.go API: Fix incorrect Swagger response schemas and "Fore more" typos 2026-04-15 15:56:13 +02:00
thumbnails_test.go Security: Use individual preview tokens for each user account #98 2022-10-13 22:11:02 +02:00
users_avatar.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
users_avatar_test.go API: Enforce pre-parse body limits for login and uploads 2026-03-07 15:31:30 +01:00
users_passcode.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
users_passcode_test.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
users_password.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
users_password_test.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
users_sessions.go API: Add missing Swagger endpoint annotations and update swagger.json 2025-09-22 04:12:02 +02:00
users_sessions_test.go Videos: Refactor codec, content and file type specifications #4770 2025-02-05 00:30:45 +01:00
users_update.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
users_update_test.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
users_upload.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
users_upload_multipart_test.go API: Enforce pre-parse body limits for login and uploads 2026-03-07 15:31:30 +01:00
users_upload_test.go API: Enforce pre-parse body limits for login and uploads 2026-03-07 15:31:30 +01:00
video.go API: Fix incorrect Swagger response schemas and "Fore more" typos 2026-04-15 15:56:13 +02:00
video_test.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
vision_caption.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
vision_caption_test.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
vision_face.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
vision_face_test.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
vision_labels.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
vision_labels_test.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
vision_nsfw.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
vision_nsfw_test.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
websocket.go Config: Gate node roles by edition and align tests/lint 2026-02-26 15:37:55 +01:00
websocket_create.go API: Add missing Swagger annotations and update swagger.json 2025-10-30 11:00:16 +01:00
websocket_reader.go Auth: Add "node" and "portal" roles, refactor session entity #98 2025-09-18 13:33:18 +02:00
websocket_test.go Auth: Refactor cluster configuration and provisioning API endpoints #98 2025-09-24 08:28:38 +02:00
websocket_topics_test.go Portal: Add cluster admin UI #98 2025-10-16 16:21:56 +02:00
websocket_writer.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
zip.go API: Export request limit helpers and align test guidance 2026-03-08 13:49:50 +01:00
zip_test.go Config: Centralize options patch persistence and update related docs 2026-02-24 10:20:16 +01:00

API Package Guide

Overview

The API package exposes PhotoPrisms HTTP endpoints via Gin handlers. Each file under internal/api contains the handlers, request/response DTOs, and Swagger annotations for a specific feature area. Handlers remain thin: they validate input, enforce security or ACL checks, and delegate domain work to services in internal/photoprism, internal/service, or other internal packages. Keep exported types aligned with the REST schema and avoid embedding business logic directly in handlers.

Routing & Wiring

  • Register handlers in internal/server/routes.go by attaching them to the proper router group (for example, APIv1 := router.Group(conf.BaseUri("/api/v1"), Api(conf))).
  • Group endpoints by resource to match existing patterns: sessions, cluster, photos, labels, files, downloads, metadata, and technical routes.
  • Apply middleware stacks (Api, AuthRequired, limiter.Auth, etc.) at the router level to keep handlers focused on request handling.
  • Use conf.BaseUri() when constructing route prefixes so configuration overrides propagate consistently.
  • When new endpoints require feature toggles, gate them in the router rather than inside the handler so disabled routes remain undiscoverable.

Handler Implementation Patterns

  • Accept and return JSON using the shared response helpers. Set header.ContentTypeJSON and ensure responses include proper cache headers (no-store for sensitive payloads).
  • Parse parameters with Gin binding and validate inputs before delegating work. For complex payloads, define dedicated request structs with validation tags.
  • Use the shared download helpers (safe.Download, avatar.SafeDownload) when calling outward HTTP APIs to inherit timeout, size, and SSRF protections.
  • Query and persist data through the corresponding services or repositories; avoid ad-hoc SQL or GORM usage in handlers when dedicated functions exist elsewhere.
  • Surface pagination consistently with count, offset, and limit following the defaults (100 max 1000). Validate offset >= 0 and clamp count to the allowed range.
  • When responses need role-specific fields, build DTOs that redact sensitive data for non-admin roles so the handler stays deterministic.

Security & Middleware

  • Authenticate requests using the standard middleware (AuthRequired) and check roles via helpers in internal/auth/acl (acl.ParseRole, acl.ScopePermits, acl.ScopeAttrPermits).
  • Bound request bodies before parsing JSON or multipart payloads. Use LimitRequestBodyBytes(...) with a route-appropriate cap before BindJSON(...) / ShouldBindJSON(...), detect IsRequestBodyTooLarge(err), and return 413 Request Entity Too Large via AbortRequestTooLarge(...).
  • Keep new JSON binding sites on the shared request-limit path by running make check-api-request-limits (also included in make lint) after adding or refactoring API handlers in the root repo or private overlays.
  • Never log secrets or tokens. Prefer structured logging through event.Log and redact sensitive values before logging.
  • Enforce rate limiting with the shared limiters (limiter.Auth, limiter.Login) and respond with limiter.AbortJSON to maintain consistent 429 JSON payloads.
  • Derive client IPs through api.ClientIP and extract bearer tokens with header.BearerToken or the helper setters. Use constant-time comparison for tokens and secrets.
  • For downloads or proxy endpoints, validate URLs against allowed schemes (http, https) and reject private or loopback addresses unless explicitly required.
  • Upload-time NSFW screening (users_upload.go) — when PHOTOPRISM_UPLOAD_NSFW=false, the upload handler runs vision.DetectNSFW against every accepted file and deletes any file flagged above the NSFW threshold before it reaches originals/. The check is skipped entirely when UPLOAD_NSFW=true (default). See internal/ai/nsfw/README.md for the full NSFW call-graph and flag matrix.

Audit Logging

  • Emit security events via event.Audit* (AuditInfo, AuditWarn, AuditErr, AuditDebug) and always build the slice as Who → What → Outcome.
    • Who: ClientIP(c) followed by the most specific actor context ("session %s", "client %s", "user %s").
    • What: Resource constant plus action segments (for example, string(acl.ResourceCluster), "node", "%s"). Place extra context such as counts or error placeholders in separate segments before the outcome.
    • Outcome: End with a single token such as status.Succeeded, status.Failed, status.Denied, or status.Error(err) when the sanitized error message should be the outcome; nothing comes after it.
  • Prefer existing helpers (ClientIP, clean.Log, clean.LogQuote, clean.Error) instead of formatting values manually, and avoid inline = expressions.
  • Example patterns:
    event.AuditInfo([]string{
        ClientIP(c),
        "session %s",
        string(acl.ResourceCluster),
        "node", "%s",
        status.Deleted,
    }, s.RefID, uuid)
    
    event.AuditErr([]string{
        clientIp,
        "session %s",
        string(acl.ResourceCluster),
        "download theme",
        status.Error(err),
    }, refID)
    

Swagger Documentation

  • Annotate handlers with Swagger comments that include full /api/v1/... paths, request/response schemas, and security definitions. Only annotate routes that are externally accessible.
  • Regenerate docs after adding or updating handlers: make fmt-go swag-fmt swag. This formats Go files, normalizes annotations, and updates internal/api/swagger.json. Do not edit the generated JSON manually.
  • When adding new DTOs, keep field names aligned with the JSON schema and update client documentation if serialized names change.
  • Use enum annotations sparingly and ensure they reflect actual runtime constraints to avoid misleading generated clients.

Testing Strategy

  • Build tests around the API harness (NewApiTest) to obtain a configured Gin router, config, and dependencies. This isolates filesystem paths and avoids polluting global state.
  • Wrap requests with helper functions (for example, PerformRequestJSON, PerformAuthenticatedRequest) to capture status codes, headers, and payloads. Assert headers using constants from pkg/http/header.
  • When handlers interact with the database, initialize fixtures through config helpers such as config.NewTestConfig("api") or config.NewMinimalTestConfigWithDb("api", t.TempDir()) depending on fixture needs.
  • Stub external dependencies (httptest.Server) for remote calls and set AllowPrivate=true explicitly when the test server binds to loopback addresses.
  • Structure tests with table-driven subtests (t.Run("CaseName", ...)) and use PascalCase names. Provide cleanup functions (t.Cleanup) to remove temporary files or databases created during tests.
  • Do not run internal/api tests in parallel. These suites share fixture files, temporary assets, and database state, so parallel go test invocations can cause false failures and readonly/fixture-conflict errors.

Focused Test Runs

  • Fast iteration: go test ./internal/api -run '<Package|HandlerName>' -count=1
  • Cluster endpoints: go test ./internal/api -run 'Cluster' -count=1
  • Downloads and zip streaming: go test ./internal/api -run 'Download|Archive' -count=1
  • Combined CLI and API validation: pair go test ./internal/commands -run 'Cluster' -count=1 with the matching API suite to ensure DTOs remain compatible.
  • Keep focused internal/api runs sequential. Do not launch multiple go test ./internal/api ... commands at the same time.

Preflight Checklist

  • Format and regenerate documentation: make fmt-go swag-fmt swag
  • Compile backend: go build ./...
  • Execute targeted API suites: go test ./internal/api -run '<Name>' -count=1
  • Run integration-heavy checks before release: go test ./internal/service/cluster/registry -count=1 alongside relevant API routes to confirm cluster DTOs stay aligned.
  • Verify that photoprism show commands --json reflects any new API-driven flags or outputs when CLI exposure changes.