photoprism/internal/api
2025-11-19 10:26:04 +01: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 Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
albums.go Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02: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: Update endpoints to return HTTP 201 when a new resource was created 2025-10-20 16:46:59 +02:00
api.go API: Add security definitions to swagger annotations 2025-05-05 16:50:33 +02:00
api_auth.go Vision: Allow use of configured service key for API authentication #5299 2025-10-30 10:02:16 +01:00
api_auth_jwt.go Auth: Remove redundant preview/download token wiring for JWT #5230 2025-10-29 15:21:49 +01:00
api_auth_jwt_test.go Vision: Allow use of configured service key for API authentication #5299 2025-10-30 10:02:16 +01:00
api_auth_test.go Cluster: Rename RoleInstance to RoleApp in service/cluster/roles.go #98 2025-10-31 16:46:42 +01:00
api_client_config.go API: Refactor "GET /api/v1/config" endpoint for JWT sessions #5230 2025-10-29 12:29:12 +01:00
api_client_config_test.go Auth: Adjust JWT default scope and ACL, add tests #5230 2025-10-29 14:28:26 +01:00
api_event.go Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02: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 Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02: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: Improve logging of bad request errors across all endpoints #271 2025-07-10 09:38:36 +02:00
batch_labels.go API: Improve logging of bad request errors across all endpoints #271 2025-07-10 09:38:36 +02:00
batch_photos.go Backend: Add security-focused tests, harden WebDAV and use safe.Download 2025-09-22 10:42:53 +02:00
batch_photos_edit.go Batch Edit: Optimize updating associated labels and albums #271 #5324 2025-11-18 17:48:12 +01:00
batch_photos_edit_test.go Tests: Improve unit tests #271 2025-11-19 10:26:04 +01:00
batch_photos_test.go API: Update endpoints to return HTTP 201 when a new resource was created 2025-10-20 16:46:59 +02: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 Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02: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 Cluster: Refactor request/response structs and JSON serialization 2025-10-18 17:42:22 +02:00
cluster_nodes.go Cluster: Improve API endpoint and CLI command logs 2025-10-21 16:51:24 +02:00
cluster_nodes_redaction_test.go Cluster: Rename RoleInstance to RoleApp in service/cluster/roles.go #98 2025-10-31 16:46:42 +01:00
cluster_nodes_register.go API: Adjust advertise URL validation in cluster_nodes_register.go 2025-10-28 13:08:52 +01:00
cluster_nodes_register_test.go Cluster: Rename RoleInstance to RoleApp in service/cluster/roles.go #98 2025-10-31 16:46:42 +01:00
cluster_nodes_test.go Cluster: Rename RoleInstance to RoleApp in service/cluster/roles.go #98 2025-10-31 16:46:42 +01:00
cluster_nodes_update_siteurl_test.go Cluster: Rename RoleInstance to RoleApp in service/cluster/roles.go #98 2025-10-31 16:46:42 +01:00
cluster_permissions_test.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
cluster_summary.go Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02:00
cluster_theme.go Logs: Replace status string literals with generic constants 2025-10-21 15:08:10 +02:00
cluster_theme_test.go Cluster: Rename RoleInstance to RoleApp in service/cluster/roles.go #98 2025-10-31 16:46:42 +01:00
config_options.go CLI: Add "photoprism vision reset" command to reset metadata #5233 2025-09-29 18:59:52 +02:00
config_options_test.go Config: Add "develop" feature flag to disable new viewer sidebar #3168 2025-02-03 12:29:02 +01:00
config_settings.go Auth: Extend user accounts with custom scope setting 2025-10-22 19:58:56 +02:00
config_settings_test.go Config: Add "develop" feature flag to disable new viewer sidebar #3168 2025-02-03 12:29:02 +01:00
connect.go Backend: Add security-focused tests, harden WebDAV and use safe.Download 2025-09-22 10:42:53 +02:00
connect_test.go API: Improve logs and add /api/v1/connect endpoint for auth callbacks 2022-07-19 16:58:43 +02: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 Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
doc_overrides.go API: Add const, func, and struct comments for easier troubleshooting 2025-09-30 22:02:43 +02:00
docs.go API: Improve Swagger annotations and update swagger.json 2025-10-30 11:47:40 +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: Update swagger endpoint documentation #5133 2025-08-28 11:13:28 +02: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: Improve logging of bad request errors across all endpoints #271 2025-07-10 09:38:36 +02: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
feedback.go API: Improve Swagger annotations and update swagger.json 2025-10-30 11:47:40 +01:00
feedback_test.go API: Add .well-known/oauth-authorization-server route handler #808 #3943 2024-01-08 14:53:39 +01: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 Index: Refactor IndexOptions to determine vision tasks from Config #5167 2025-10-07 16:22:41 +02: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 Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02: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: Add missing Swagger annotations and update swagger.json 2025-10-30 11:00:16 +01:00
import_test.go Tests: Add unit tests 2025-03-12 16:34:28 +01:00
index.go API: Add missing Swagger annotations and update swagger.json 2025-10-30 11:00:16 +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: Update Thumb/ThumbSrc for subjects and labels #4151 2025-10-03 23:17:07 +02:00
labels_search.go AI: Include NSFW flag & score when generating labels with Ollama #5232 2025-10-05 04:23:36 +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 Backend: Add security-focused tests, harden WebDAV and use safe.Download 2025-09-22 10:42:53 +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: Update endpoints to return HTTP 201 when a new resource was created 2025-10-20 16:46:59 +02:00
markers_test.go API: Update endpoints to return HTTP 201 when a new resource was created 2025-10-20 16:46:59 +02:00
metrics.go AI: Enhance "GET /api/v1/metrics" endpoint with additional stats #213 2025-10-31 15:38:10 +01:00
metrics_test.go Cluster: Change "photoprism_" database / user prefix to "cluster_" #98 2025-10-31 18:18:18 +01:00
moments_time.go API: Add Swagger annotations #2132 2024-09-04 13:50:24 +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 Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02:00
oauth_revoke_test.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
oauth_token.go Logs: Replace status string literals with generic constants 2025-10-21 15:08:10 +02:00
oauth_token_ratelimit_test.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02: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 Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
oidc_login_test.go Tests: Add unit tests 2024-07-17 16:35:49 +02:00
oidc_redirect.go OIDC: Ensure ID tokens fit into the auth_sessions.id_token column #5294 2025-11-14 17:02:17 +01:00
oidc_redirect_test.go Videos: Refactor codec, content and file type specifications #4770 2025-02-05 00:30:45 +01:00
options.go API: Update swagger endpoint documentation #5133 2025-08-28 11:00:19 +02:00
photo_label.go Merge branch 'develop' into feature/batch-edit 2025-09-30 01:20:14 +02:00
photo_label_test.go Merge branch 'develop' into feature/batch-edit 2025-10-10 10:17:52 +02:00
photo_unstack.go Index: Refactor IndexOptions to determine vision tasks from Config #5167 2025-10-07 16:22:41 +02:00
photo_unstack_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
photos.go Config: Add fs.ExtYml file extension const for transitioning to ".yaml" 2025-09-13 02:09:22 +02:00
photos_search.go Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +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 Auth: Refactor cluster configuration and provisioning API endpoints #98 2025-09-24 08:28:38 +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 Cluster: Improve API endpoint and CLI command logs 2025-10-21 16:51:24 +02:00
server.go API: Improve Swagger annotations and update swagger.json 2025-10-30 11:47:40 +01:00
services.go API: Update endpoints to return HTTP 201 when a new resource was created 2025-10-20 16:46:59 +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: Improve logging of bad request errors across all endpoints #271 2025-07-10 09:38:36 +02: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 Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02: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 Backend: Add security-focused tests, harden WebDAV and use safe.Download 2025-09-22 10:42:53 +02: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 Demo: Improve protection against AI-generated reports #5269 2025-10-17 19:34:39 +02:00
share.go API: Improve Swagger annotations and update swagger.json 2025-10-30 11:41:33 +01:00
share_preview.go API: Improve Swagger annotations and update swagger.json 2025-10-30 11:41:33 +01: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: Add missing Swagger annotations and update swagger.json 2025-10-30 11:00:16 +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: Improve logging of bad request errors across all endpoints #271 2025-07-10 09:38:36 +02: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 AI: Update internal/api/swagger.json #5322 2025-11-14 12:06:19 +01:00
thumbnails.go API: Add missing Swagger endpoint annotations and update swagger.json 2025-09-22 04:12:02 +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 Logs: Replace status string literals with generic constants 2025-10-21 15:08:10 +02:00
users_avatar_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
users_passcode.go Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02:00
users_passcode_test.go API: Update endpoints to return HTTP 201 when a new resource was created 2025-10-20 16:46:59 +02:00
users_password.go API: Add missing Swagger endpoint annotations and update swagger.json 2025-09-22 04:12:02 +02:00
users_password_test.go Auth: Refactor cluster configuration and provisioning API endpoints #98 2025-09-24 08:28:38 +02: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: Add missing Swagger endpoint annotations and update swagger.json 2025-09-22 04:12:02 +02:00
users_update_test.go Auth: Refactor cluster configuration and provisioning API endpoints #98 2025-09-24 08:28:38 +02:00
users_upload.go Logs: Replace status string literals with generic constants 2025-10-21 15:08:10 +02:00
users_upload_multipart_test.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
users_upload_test.go Backend: Add security-focused tests, harden WebDAV and use safe.Download 2025-09-22 10:42:53 +02:00
video.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +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 Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
vision_face.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
vision_face_test.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
vision_labels.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
vision_labels_test.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
vision_nsfw.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
vision_nsfw_test.go Pkg: Move /service/http/... to /http/... and add package /http/dns 2025-10-19 21:08:48 +02:00
websocket.go API: Implement OIDC redirect endpoint #782 2024-07-01 16:50:53 +02: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 Portal: Add cluster admin UI #98 2025-10-16 16:21:56 +02:00
zip.go Auth: Refactor cluster configuration and provisioning API endpoints #98 2025-09-24 08:28:38 +02:00
zip_test.go Import: Add ytdl package for downloading videos from URLs #4982 2025-05-02 10:04:34 +02: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).
  • 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.

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)
    
  • See specs/common/audit-logs.md for the full conventions and additional examples that agents should follow.

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.

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.

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.