| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 0 | 14 | 14 | 0% |
| Commands | 17 | 23 | 7 | 36% |
| Section tags | 8 | 3 | 1 | 67% |
What each file covers
Sections
0 shared · 14 only in A · 14 only in B- − CLAUDE.md
- − Build Commands
- − Testing
- − Formatting & Linting
- − Continuous Integration
- − Schema Migrations
- − or via Makefile:
- − Architecture Overview
- − Backend (`internal/`, `pkg/`, `cmd/`)
- − Frontend (`frontend/`)
- − API Conventions
- − Config & Flags
- − Verify Before Propagating
- − Detailed Rules
- + Instructions for GitHub Copilot
- + Purpose
- + Single Sources of Truth (SOT)
- + Build & Run (local dev; use Makefile first)
- + Tests & Lint
- + Project Structure & Languages
- + Code Review Instructions (for Copilot)
- + Style & Patterns
- + Commits & Pull Requests
- + Performance & Reliability
- + When Unsure
- + References To Help Copilot Answer Questions
- + Output Expectations
- + Safety Checklist Before Proposing a CLI Command
Commands
17 shared · 23 only in A · 7 only in B- − go test ./internal/api -run 'TestFunctionName' -count=1
- − go test ./internal/photoprism -run 'TestMediaFile_' -count=1
- − go test ./internal/entity/... -count=1 -tags="slow,develop"
- − go run cmd/photoprism/photoprism.go migrations ls
- − go run cmd/photoprism/photoprism.go migrations run
- − make migrate
- − make build-all
- − go build ./...
- − make dep-js
- − npm ci
- − npm rebuild --ignore-scripts=false <pkg>
- − npm rebuild
- − make terminal
- − make reset-testdb
- − make test-pkg
- − make test-api
- − make test-entity
- − make test-commands
- − make test-photoprism
- − make test-ai
- − make fmt
- − make fmt-swag
- − make swag
- + docker compose logs -f --tail=100 photoprism
- + go test ./internal/<pkg> -run '<TestName>' -count=1
- + make lint-js
- + make fmt-go swag-fmt swag
- + go.mod
- + go.sum
- + make notice
- make help
- make list
- make build-go
- make build-js
- make watch-js
- make dep
- make docker-build
- docker compose up
- make test
- make test-go
- make test-js
- make test-short
- make vitest-watch
- make vitest-coverage
- make fmt-go
- make fmt-js
- make lint-go
Section tags
8 shared · 3 only in A · 1 only in B- − types
- − database
- − api
- + performance
- build
- test
- lint-format
- code-style
- architecture
- git-pr
- do-not
- agent-behaviour
Line diff
photoprism/photoprism · .claude/CLAUDE.md
@@ −1 @@
1# CLAUDE.md
2
3This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. Detailed rules are in `.claude/rules/*.md` files organized by topic.
4
5## Build Commands
6
7Run `make help` for an overview of the most common targets, and `make list` to list all of them. Key commands:
8
9**Backend (Go):**
10- `make build-go` — build the `photoprism` binary (develop mode)
11- `make build-all` — build backend + frontend
12- `go build ./...` — compile all Go packages
13
14**Frontend (Vue 3):**
15- `make build-js` — production build of the frontend
16- `make watch-js` — watch mode for frontend development (Ctrl+C to stop)
17
18**Dependencies:**
19- `make dep` — install all dependencies (TensorFlow models, ONNX models, JS packages)
20- `make dep-js` — install JS dependencies only (`npm ci`). The `photoprism/develop` image and the repo `Makefile` both set `NPM_CONFIG_IGNORE_SCRIPTS=true`, so install scripts are skipped automatically; when running npm directly in an env without that default, pass `--ignore-scripts`. Rebuild native addons with `npm rebuild --ignore-scripts=false <pkg>` — a bare `npm rebuild` no-ops wherever the env default is active.
21
22**Docker dev environment:**
23- `make docker-build` — build local Docker image
24- `docker compose up` — start dev environment (app at http://localhost:2342/)
25- `make terminal` — open shell in dev container
26
27## Testing
28
29**Run all tests:**
30- `make test` — runs both JS and Go tests
31- `make test-go` — all Go tests (slow, ~20 min)
32- `make test-js` — frontend unit tests (Vitest)
33- `make test-short` — short Go tests in parallel (~5 min)
34
35**Run targeted Go tests:**
36```bash
37go test ./internal/api -run 'TestFunctionName' -count=1
38go test ./internal/photoprism -run 'TestMediaFile_' -count=1
39go test ./internal/entity/... -count=1 -tags="slow,develop"
40```
41
42**Run targeted JS tests:**
43- `make vitest-watch` — Vitest in watch mode
44- `make vitest-coverage` — Vitest with coverage report
45
46**Reset test databases before running Go tests:**
47- `make reset-testdb` — clears SQLite test DBs and MariaDB testdb
48
49**Subset targets:** `make test-pkg`, `make test-api`, `make test-entity`, `make test-commands`, `make test-photoprism`, `make test-ai`
50
51## Formatting & Linting
52
53Available targets: `make fmt` (everything), `make fmt-go`, `make fmt-js`, `make fmt-swag` / `make swag` (Swagger), `make lint-go`, `make lint-js`. Detailed conventions live in `.claude/rules/go-code-style.md` and `.claude/rules/frontend-rules.md`.
54
55When creating or editing shell scripts, run `shellcheck <file>` and resolve warnings. When editing Markdown files that contain tables, format them with `npx --yes markdown-table-formatter <filename>`.
56
57The curated `make help` overviews are maintained by hand in a `HELP_TEXT` block per Makefile. After renaming or removing a target, run `make check-make-help` (also part of `make lint`) to confirm that no overview still advertises it.
58
59## Continuous Integration
60
61**GitHub Actions is not enabled for this repository.** The workflow files under `.github/workflows/` do not execute, so pushes and pull requests produce no check runs. Treat them as dormant configuration: do not diagnose the absence of runs as a broken workflow, do not propose enabling Actions, and do not add workflows or bot configuration that assumes they will run. Ask a maintainer before changing anything under `.github/workflows/`.
62
63The `make` targets above are the authoritative build, format, and test gate — run them locally and report the output rather than relying on a hosted runner.
64
65## Schema Migrations
66
67If a change touches database schema, check migrations:
68```bash
69go run cmd/photoprism/photoprism.go migrations ls
70go run cmd/photoprism/photoprism.go migrations run
71# or via Makefile:
72make migrate
73```
74
75Migration files live in `internal/entity/migrate/`.
76
77## Architecture Overview
78
79PhotoPrism is a self-hosted photo management app. The backend is Go, the frontend is Vue 3 + Vuetify 3, and the database is MariaDB or SQLite (via GORM).
80
81### Backend (`internal/`, `pkg/`, `cmd/`)
82
83| Package | Purpose |
84|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
85| `internal/photoprism` | **Core application logic**: indexing originals, metadata extraction, thumbnail generation, import/stacking, converter orchestration (FFmpeg/ImageMagick/ExifTool). Entry point for workers and CLI. |
86| `internal/entity` | **Database models** (GORM): Photo, File, Album, Label, Face, User, Session, etc. Contains fixtures for tests and migration helpers. |
87| `internal/entity/query` | Database query helpers used by the API and core packages. |
88| `internal/api` | **REST API handlers** (Gin): thin handlers that validate input, enforce ACL/auth, delegate to services. Annotated with Swagger comments. |
89| `internal/server` | HTTP server setup, routing (Gin engine), WebDAV, static assets, middleware wiring. Routes are registered in `routes.go`. |
90| `internal/config` | Application configuration: CLI flags, env vars, client config sent to the frontend. |
91| `internal/workers` | Background workers: indexing scheduler, metadata sync, sharing, backup, vision jobs. |
92| `internal/commands` | CLI command implementations (`github.com/urfave/cli/v2`). |
93| `internal/auth` | Authentication: ACL (`auth/acl`), JWT (`auth/jwt`), OIDC (`auth/oidc`), session management. |
94| `internal/form` | Request form/binding structs for the API layer. |
95| `internal/meta` | Metadata extraction from EXIF, XMP, JSON sidecars. |
96| `internal/ffmpeg` | FFmpeg/transcoding helpers. |
97| `internal/thumb` | Thumbnail generation helpers. |
98| `internal/ai` | AI/vision model integration (TensorFlow, ONNX). |
99| `internal/service` | Services: maps geocoding, hub (membership), cluster, WebDAV client, CIDR helpers. |
100| `internal/event` | Event bus for structured logging and audit events. |
101| `pkg/` | Standalone, reusable packages: `fs`, `geo`, `media`, `txt`, `clean`, `rnd`, `i18n`, `http`, `time`, etc. No dependency on `internal/`. |
102
103**Request flow:** HTTP request → Gin middleware (auth, rate limiting) → `internal/api` handler → `internal/photoprism` or `internal/entity` → response.
104
105**Audit logging convention** (`event.AuditInfo/Warn/Err`): slices must follow the pattern **Who → What → Outcome**:
106- Who: `ClientIP(c)` + actor context (`"session %s"`, `"user %s"`)
107- What: resource constant + action segments
108- Outcome: single token like `status.Succeeded`, `status.Failed`, `status.Denied`, `status.Error(err)`
109
110### Frontend (`frontend/`)
111
112Vue 3 app using the Options API and Vuetify 3.
113
114| Directory | Purpose |
115|---------------------------|-------------------------------------------------------------------------------------------------|
116| `frontend/src/model/` | Client-side models mirroring API responses (Photo, Album, File, User, etc.) |
117| `frontend/src/app/` | App bootstrap, routing (`routes.js`), and the `$session` reactive singleton |
118| `frontend/src/page/` | Page-level components |
119| `frontend/src/component/` | Reusable UI components |
120| `frontend/src/common/` | Shared utilities, the API client (`$api`), and reactive singletons (`$config`, `$view`, `$log`) |
121| `frontend/src/locales/` | i18n translation files |
122| `frontend/tests/` | Vitest unit tests + TestCafe acceptance tests |
123
124State management uses reactive singleton modules in `src/common/` and `src/app/`, not Vuex or Pinia. Frontend code-style, formatting, testing, translation, and Playwright rules live in `.claude/rules/frontend-rules.md`.
125
126### API Conventions
127
128- REST API v1 base path: `/api/v1/` (configured via `conf.BaseUri()`)
129- Authentication: Bearer token (`Authorization` header) or `X-Auth-Token` header
130- Pagination: `count`, `offset`, `limit` parameters (default 100, max 1000)
131- After adding/changing API handlers, regenerate Swagger docs: `make fmt-go swag-fmt swag`
132- New routes must be registered in `internal/server/routes.go`
133
134### Config & Flags
135
136Verify config option names before using them:
137```bash
138./photoprism --help
139./photoprism show config-options
140./photoprism show config-yaml
141```
142
143### Verify Before Propagating
144
145Before promoting a claim from `CLAUDE.md`, `AGENTS.md`, a memory entry, or another spec into a new rule, spec, code comment, or commit message, verify it against the current code (grep imports, list directories, read the cited file). Stale documentation silently turns into stale rules and stale specs that future sessions will trust. When the claim names a package, function, file, or framework, the cost of one grep is much smaller than the cost of repeating an error across multiple files.
146
147### Detailed Rules
148
149Topic-specific conventions live under `.claude/rules/` and are loaded alongside this file:
150
151- `code-comments.md` — shared JS/Go doc comment rules (length cap, what to omit); referenced by both style files.
152- `go-code-style.md`, `go-testing.md` — Go style, package boundaries, test patterns, fixtures.
153- `frontend-rules.md` — JS/Vue code style, formatting, dependencies, tests, Playwright, translations.
154- `commit-and-docs-style.md` — commit-message format, GitHub issue templates, spec heading style.
155- `safety-and-security.md` — Git/data safety, destructive commands, file I/O and archive-extraction policies, HTTP download helpers.
156- `api-and-config.md`, `cluster-operations.md`, `import-index-download.md`, `build-and-runtime.md`, `sources-of-truth.md` — domain-specific guidance.
157
photoprism/photoprism · .github/copilot-instructions.md
@@ +1 @@
1# Instructions for GitHub Copilot
2
3**Last Updated:** July 28, 2026
4
5## Purpose
6
7- Provide Copilot with the single sources of truth for building, testing, and contributing to PhotoPrism.
8- Improve PR reviews and code suggestions by aligning them with our documented workflows and style.
9- Path-specific rules that apply on top of this file live in `.github/instructions/*.instructions.md`.
10
11## Single Sources of Truth (SOT)
12
13- Makefile targets (always prefer existing targets): https://github.com/photoprism/photoprism/blob/develop/Makefile
14- Developer Guide – Setup: https://docs.photoprism.app/developer-guide/setup/
15- Developer Guide – Tests: https://docs.photoprism.app/developer-guide/tests/
16- Contributing: https://github.com/photoprism/photoprism/blob/develop/CONTRIBUTING.md
17- Security: https://github.com/photoprism/photoprism/blob/develop/SECURITY.md
18- REST API (Swagger): https://docs.photoprism.dev/
19- REST API Guide: https://docs.photoprism.app/developer-guide/api/
20- Agents reference for tools/commands: https://github.com/photoprism/photoprism/blob/develop/AGENTS.md
21- Code maps: https://github.com/photoprism/photoprism/blob/develop/CODEMAP.md (backend) and https://github.com/photoprism/photoprism/blob/develop/frontend/CODEMAP.md (frontend)
22- Terminology: https://github.com/photoprism/photoprism/blob/develop/GLOSSARY.md
23
24## Build & Run (local dev; use Makefile first)
25
26- Show common tasks: `make help` (`make list` shows all targets)
27- Build local image: `make docker-build`
28- Start dev env: `docker compose up` (add `-d` for detached, or run `make up`)
29- Logs: `docker compose logs -f --tail=100 photoprism`
30- Open app: http://localhost:2342/ (HTTP) / https://app.localssl.dev/ (TLS via Traefik when enabled)
31- From the dev container:
32 - Install deps: `make dep`
33 - Build frontend: `make build-js` (or `cd frontend && npm run build`)
34 - Build backend: `make build-go`
35 - Watch frontend: `make watch-js` (stop with Ctrl+C)
36 - Run server binary: `./photoprism start`
37
38## Tests & Lint
39
40- Full tests: `make test`
41- Frontend tests (Vitest): `make test-js` (watch: `make vitest-watch`, coverage: `make vitest-coverage`)
42- Backend tests: `make test-go` (slow); `make test-short` for a fast parallel run
43- Targeted Go tests: `go test ./internal/<pkg> -run '<TestName>' -count=1`
44- Formatting and linting:
45 - Go: `make fmt-go` (gofmt + goimports) and `make lint-go` (golangci-lint)
46 - JS/Vue: `make fmt-js` and `make lint-js`. ESLint owns JS and Vue; Prettier owns CSS/SCSS/SASS only. ESLint does not run Prettier, so do not propose reflowing JS to satisfy Prettier.
47- Swagger: after changing API handlers or annotations, run `make fmt-go swag-fmt swag`; never edit `internal/api/swagger.json` by hand.
48- Dependencies: when `go.mod`, `go.sum`, or `package-lock.json` change, regenerate the license reports with `make notice`; never edit `NOTICE` or `frontend/NOTICE` manually.
49
50## Project Structure & Languages
51
52- Backend: Go (`internal/`, `pkg/`, `cmd/`) + MariaDB/SQLite
53- Frontend: Vue 3 + Vuetify 3 (`frontend/`)
54- Docker/compose for dev/CI; Traefik used for local TLS in dev profile when enabled.
55- A maintainer's working copy may contain private subdirectories (`plus/`, `pro/`, `portal/`, `specs/`) that are not part of this repository. Never reference their paths from public artifacts such as pull request descriptions, issue comments, or code comments — external readers only see a broken link.
56
57## Code Review Instructions (for Copilot)
58
59- Respect SOT above; do not invent flags, env vars, or Compose options. If a command/env var is not in the docs/Makefile/CLI help, say "not documented" and suggest checking the SOT.
60- Prefer minimal, surgical diffs. Propose changes as concrete patches and reference the relevant Makefile target or doc section.
61- Before suggesting refactors, check tests and build tasks exist and can pass with the change. If tests are missing, suggest specific Vitest/Go test snippets.
62- Security: never suggest committing secrets; prefer env vars and `.env` in dev only. Point to SECURITY.md for disclosures.
63- Data safety: never run or recommend destructive CLI operations in examples without explicit backups and `--yes`. Avoid `photoprism reset`, `photoprism users reset`, `photoprism auth reset`, or `photoprism audit reset` in PR comments unless the change is specifically about those commands; if unavoidable, add bold warnings and backup steps.
64- Database/schema: if a change touches persistence, check for migrations and mention `photoprism migrate` / `migrations` commands.
65- API changes: align with the REST API docs/spec; include curl examples only if they match current endpoints and auth notes.
66- UX/i18n: keep UI strings concise, translatable, and consistent; avoid hard-coded language constructs; prefer existing patterns/components.
67
68## Style & Patterns
69
70- Go: idiomatic Go, clear error handling, small functions, packages with focused responsibilities. Keep the public surface minimal.
71 - Every added function, including unexported helpers and helpers extracted by a refactor, needs focused coverage in a sibling `*_test.go`.
72 - Code in `pkg/*` must not import from `internal/*`; new code that needs config, entity, or DB access belongs under `internal/`.
73 - Use the permission constants in `pkg/fs` (`fs.ModeDir`, `fs.ModeFile`, `fs.ModeConfigFile`, `fs.ModeSecretFile`) instead of literal file modes.
74 - Doc comments start with the name and stay compact — one line for the "what", plus a line or two only when the "why" cannot be inferred from the code. No issue numbers or change history in comments.
75- Vue/JS: Options API only. Do not introduce TypeScript (no `.ts` files, no `<script lang="ts">`), Composition API, or `<script setup>`.
76 - Shared state lives in reactive singleton modules under `src/common/` and `src/app/`. Do not propose Vuex or Pinia.
77 - Every user-visible string must go through `$gettext`, so it reaches `frontend/src/locales/translations.pot`. Standardized technical identifiers (`Client ID`, `OIDC`, `UUID`) stay literal.
78 - Prefer existing components and model methods over raw `$api` calls in components.
79- Config & flags: suggest `photoprism --help`, `photoprism show config-options` or `photoprism show config-yaml` to verify names before using them.
80
81## Commits & Pull Requests
82
83- Commit subjects use the imperative mood with a one-word scope prefix, for example `Config: Add tests for "darktable-cli" path detection`, and must not exceed 80 characters.
84- Reference related issue or PR IDs in the message when applicable, for example `Docker: Use two stage build to reduce image size #123 #5632`.
85- Do not add AI-authorship trailers such as `Co-Authored-By: Copilot` — this repository uses no commit trailers.
86- Issue titles follow the same prefix style; descriptions open with a bold user story (`**As a <role>, I want <goal>, so that <outcome>.**`) and close with a checklist of acceptance criteria using MUST, SHOULD, or MAY.
87- Commit messages, code comments, and public issue or PR text must not describe exploitable details of a security fix; present such changes as general hardening.
88
89## Performance & Reliability
90
91- Prefer using existing caches, workers, and batching strategies referenced in code and Makefile. Consider memory/CPU impact; suggest benchmarks or profiling only when justified.
92
93## When Unsure
94
95- Ask for the exact Makefile target or doc link you need, then proceed. Defer to SOT if any conflict arises.
96
97## References To Help Copilot Answer Questions
98
99- Show supported formats/filters: run `photoprism show file-formats` and `photoprism show search-filters` (use results rather than guessing).
100- For CI/dev containers, assume a Linux/Unix shell on amd64 or arm64 by default; for Windows specifics, link https://docs.photoprism.app/developer-guide/faq/
101
102## Output Expectations
103
104- Prefer short, actionable comments with code blocks that pass tests locally: `make test-js` (frontend) / `make test-go` (backend)
105- If a suggestion requires additional context (e.g., DB access, external service), call it out explicitly.
106
107## Safety Checklist Before Proposing a CLI Command
108
109- Include a dry-run or non-destructive variant if possible.
110- Recommend creating/using backups before any reset/migrate.
111
@@ −1 +1 @@
1−# CLAUDE.md
1+# Instructions for GitHub Copilot
22
3−This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. Detailed rules are in `.claude/rules/*.md` files organized by topic.
3+**Last Updated:** July 28, 2026
44
5−## Build Commands
5+## Purpose
66
7−Run `make help` for an overview of the most common targets, and `make list` to list all of them. Key commands:
7+- Provide Copilot with the single sources of truth for building, testing, and contributing to PhotoPrism.
8+- Improve PR reviews and code suggestions by aligning them with our documented workflows and style.
9+- Path-specific rules that apply on top of this file live in `.github/instructions/*.instructions.md`.
810
9−**Backend (Go):**
10−- `make build-go` — build the `photoprism` binary (develop mode)
11−- `make build-all` — build backend + frontend
12−- `go build ./...` — compile all Go packages
11+## Single Sources of Truth (SOT)
1312
14−**Frontend (Vue 3):**
15−- `make build-js` — production build of the frontend
16−- `make watch-js` — watch mode for frontend development (Ctrl+C to stop)
13+- Makefile targets (always prefer existing targets): https://github.com/photoprism/photoprism/blob/develop/Makefile
14+- Developer Guide – Setup: https://docs.photoprism.app/developer-guide/setup/
15+- Developer Guide – Tests: https://docs.photoprism.app/developer-guide/tests/
16+- Contributing: https://github.com/photoprism/photoprism/blob/develop/CONTRIBUTING.md
17+- Security: https://github.com/photoprism/photoprism/blob/develop/SECURITY.md
18+- REST API (Swagger): https://docs.photoprism.dev/
19+- REST API Guide: https://docs.photoprism.app/developer-guide/api/
20+- Agents reference for tools/commands: https://github.com/photoprism/photoprism/blob/develop/AGENTS.md
21+- Code maps: https://github.com/photoprism/photoprism/blob/develop/CODEMAP.md (backend) and https://github.com/photoprism/photoprism/blob/develop/frontend/CODEMAP.md (frontend)
22+- Terminology: https://github.com/photoprism/photoprism/blob/develop/GLOSSARY.md
1723
18−**Dependencies:**
19−- `make dep` — install all dependencies (TensorFlow models, ONNX models, JS packages)
20−- `make dep-js` — install JS dependencies only (`npm ci`). The `photoprism/develop` image and the repo `Makefile` both set `NPM_CONFIG_IGNORE_SCRIPTS=true`, so install scripts are skipped automatically; when running npm directly in an env without that default, pass `--ignore-scripts`. Rebuild native addons with `npm rebuild --ignore-scripts=false <pkg>` — a bare `npm rebuild` no-ops wherever the env default is active.
24+## Build & Run (local dev; use Makefile first)
2125
22−**Docker dev environment:**
23−- `make docker-build` — build local Docker image
24−- `docker compose up` — start dev environment (app at http://localhost:2342/)
25−- `make terminal` — open shell in dev container
26+- Show common tasks: `make help` (`make list` shows all targets)
27+- Build local image: `make docker-build`
28+- Start dev env: `docker compose up` (add `-d` for detached, or run `make up`)
29+- Logs: `docker compose logs -f --tail=100 photoprism`
30+- Open app: http://localhost:2342/ (HTTP) / https://app.localssl.dev/ (TLS via Traefik when enabled)
31+- From the dev container:
32+ - Install deps: `make dep`
33+ - Build frontend: `make build-js` (or `cd frontend && npm run build`)
34+ - Build backend: `make build-go`
35+ - Watch frontend: `make watch-js` (stop with Ctrl+C)
36+ - Run server binary: `./photoprism start`
2637
27−## Testing
38+## Tests & Lint
2839
29−**Run all tests:**
30−- `make test` — runs both JS and Go tests
31−- `make test-go` — all Go tests (slow, ~20 min)
32−- `make test-js` — frontend unit tests (Vitest)
33−- `make test-short` — short Go tests in parallel (~5 min)
40+- Full tests: `make test`
41+- Frontend tests (Vitest): `make test-js` (watch: `make vitest-watch`, coverage: `make vitest-coverage`)
42+- Backend tests: `make test-go` (slow); `make test-short` for a fast parallel run
43+- Targeted Go tests: `go test ./internal/<pkg> -run '<TestName>' -count=1`
44+- Formatting and linting:
45+ - Go: `make fmt-go` (gofmt + goimports) and `make lint-go` (golangci-lint)
46+ - JS/Vue: `make fmt-js` and `make lint-js`. ESLint owns JS and Vue; Prettier owns CSS/SCSS/SASS only. ESLint does not run Prettier, so do not propose reflowing JS to satisfy Prettier.
47+- Swagger: after changing API handlers or annotations, run `make fmt-go swag-fmt swag`; never edit `internal/api/swagger.json` by hand.
48+- Dependencies: when `go.mod`, `go.sum`, or `package-lock.json` change, regenerate the license reports with `make notice`; never edit `NOTICE` or `frontend/NOTICE` manually.
3449
35−**Run targeted Go tests:**
36−```bash
37−go test ./internal/api -run 'TestFunctionName' -count=1
38−go test ./internal/photoprism -run 'TestMediaFile_' -count=1
39−go test ./internal/entity/... -count=1 -tags="slow,develop"
40−```
50+## Project Structure & Languages
4151
42−**Run targeted JS tests:**
43−- `make vitest-watch` — Vitest in watch mode
44−- `make vitest-coverage` — Vitest with coverage report
52+- Backend: Go (`internal/`, `pkg/`, `cmd/`) + MariaDB/SQLite
53+- Frontend: Vue 3 + Vuetify 3 (`frontend/`)
54+- Docker/compose for dev/CI; Traefik used for local TLS in dev profile when enabled.
55+- A maintainer's working copy may contain private subdirectories (`plus/`, `pro/`, `portal/`, `specs/`) that are not part of this repository. Never reference their paths from public artifacts such as pull request descriptions, issue comments, or code comments — external readers only see a broken link.
4556
46−**Reset test databases before running Go tests:**
47−- `make reset-testdb` — clears SQLite test DBs and MariaDB testdb
57+## Code Review Instructions (for Copilot)
4858
49−**Subset targets:** `make test-pkg`, `make test-api`, `make test-entity`, `make test-commands`, `make test-photoprism`, `make test-ai`
59+- Respect SOT above; do not invent flags, env vars, or Compose options. If a command/env var is not in the docs/Makefile/CLI help, say "not documented" and suggest checking the SOT.
60+- Prefer minimal, surgical diffs. Propose changes as concrete patches and reference the relevant Makefile target or doc section.
61+- Before suggesting refactors, check tests and build tasks exist and can pass with the change. If tests are missing, suggest specific Vitest/Go test snippets.
62+- Security: never suggest committing secrets; prefer env vars and `.env` in dev only. Point to SECURITY.md for disclosures.
63+- Data safety: never run or recommend destructive CLI operations in examples without explicit backups and `--yes`. Avoid `photoprism reset`, `photoprism users reset`, `photoprism auth reset`, or `photoprism audit reset` in PR comments unless the change is specifically about those commands; if unavoidable, add bold warnings and backup steps.
64+- Database/schema: if a change touches persistence, check for migrations and mention `photoprism migrate` / `migrations` commands.
65+- API changes: align with the REST API docs/spec; include curl examples only if they match current endpoints and auth notes.
66+- UX/i18n: keep UI strings concise, translatable, and consistent; avoid hard-coded language constructs; prefer existing patterns/components.
5067
51−## Formatting & Linting
68+## Style & Patterns
5269
53−Available targets: `make fmt` (everything), `make fmt-go`, `make fmt-js`, `make fmt-swag` / `make swag` (Swagger), `make lint-go`, `make lint-js`. Detailed conventions live in `.claude/rules/go-code-style.md` and `.claude/rules/frontend-rules.md`.
70+- Go: idiomatic Go, clear error handling, small functions, packages with focused responsibilities. Keep the public surface minimal.
71+ - Every added function, including unexported helpers and helpers extracted by a refactor, needs focused coverage in a sibling `*_test.go`.
72+ - Code in `pkg/*` must not import from `internal/*`; new code that needs config, entity, or DB access belongs under `internal/`.
73+ - Use the permission constants in `pkg/fs` (`fs.ModeDir`, `fs.ModeFile`, `fs.ModeConfigFile`, `fs.ModeSecretFile`) instead of literal file modes.
74+ - Doc comments start with the name and stay compact — one line for the "what", plus a line or two only when the "why" cannot be inferred from the code. No issue numbers or change history in comments.
75+- Vue/JS: Options API only. Do not introduce TypeScript (no `.ts` files, no `<script lang="ts">`), Composition API, or `<script setup>`.
76+ - Shared state lives in reactive singleton modules under `src/common/` and `src/app/`. Do not propose Vuex or Pinia.
77+ - Every user-visible string must go through `$gettext`, so it reaches `frontend/src/locales/translations.pot`. Standardized technical identifiers (`Client ID`, `OIDC`, `UUID`) stay literal.
78+ - Prefer existing components and model methods over raw `$api` calls in components.
79+- Config & flags: suggest `photoprism --help`, `photoprism show config-options` or `photoprism show config-yaml` to verify names before using them.
5480
55−When creating or editing shell scripts, run `shellcheck <file>` and resolve warnings. When editing Markdown files that contain tables, format them with `npx --yes markdown-table-formatter <filename>`.
81+## Commits & Pull Requests
5682
57−The curated `make help` overviews are maintained by hand in a `HELP_TEXT` block per Makefile. After renaming or removing a target, run `make check-make-help` (also part of `make lint`) to confirm that no overview still advertises it.
83+- Commit subjects use the imperative mood with a one-word scope prefix, for example `Config: Add tests for "darktable-cli" path detection`, and must not exceed 80 characters.
84+- Reference related issue or PR IDs in the message when applicable, for example `Docker: Use two stage build to reduce image size #123 #5632`.
85+- Do not add AI-authorship trailers such as `Co-Authored-By: Copilot` — this repository uses no commit trailers.
86+- Issue titles follow the same prefix style; descriptions open with a bold user story (`**As a <role>, I want <goal>, so that <outcome>.**`) and close with a checklist of acceptance criteria using MUST, SHOULD, or MAY.
87+- Commit messages, code comments, and public issue or PR text must not describe exploitable details of a security fix; present such changes as general hardening.
5888
59−## Continuous Integration
89+## Performance & Reliability
6090
61−**GitHub Actions is not enabled for this repository.** The workflow files under `.github/workflows/` do not execute, so pushes and pull requests produce no check runs. Treat them as dormant configuration: do not diagnose the absence of runs as a broken workflow, do not propose enabling Actions, and do not add workflows or bot configuration that assumes they will run. Ask a maintainer before changing anything under `.github/workflows/`.
91+- Prefer using existing caches, workers, and batching strategies referenced in code and Makefile. Consider memory/CPU impact; suggest benchmarks or profiling only when justified.
6292
63−The `make` targets above are the authoritative build, format, and test gate — run them locally and report the output rather than relying on a hosted runner.
93+## When Unsure
6494
65−## Schema Migrations
95+- Ask for the exact Makefile target or doc link you need, then proceed. Defer to SOT if any conflict arises.
6696
67−If a change touches database schema, check migrations:
68−```bash
69−go run cmd/photoprism/photoprism.go migrations ls
70−go run cmd/photoprism/photoprism.go migrations run
71−# or via Makefile:
72−make migrate
73−```
97+## References To Help Copilot Answer Questions
7498
75−Migration files live in `internal/entity/migrate/`.
99+- Show supported formats/filters: run `photoprism show file-formats` and `photoprism show search-filters` (use results rather than guessing).
100+- For CI/dev containers, assume a Linux/Unix shell on amd64 or arm64 by default; for Windows specifics, link https://docs.photoprism.app/developer-guide/faq/
76101
77−## Architecture Overview
102+## Output Expectations
78103
79−PhotoPrism is a self-hosted photo management app. The backend is Go, the frontend is Vue 3 + Vuetify 3, and the database is MariaDB or SQLite (via GORM).
104+- Prefer short, actionable comments with code blocks that pass tests locally: `make test-js` (frontend) / `make test-go` (backend)
105+- If a suggestion requires additional context (e.g., DB access, external service), call it out explicitly.
80106
81−### Backend (`internal/`, `pkg/`, `cmd/`)
107+## Safety Checklist Before Proposing a CLI Command
82108
83−| Package | Purpose |
84−|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
85−| `internal/photoprism` | **Core application logic**: indexing originals, metadata extraction, thumbnail generation, import/stacking, converter orchestration (FFmpeg/ImageMagick/ExifTool). Entry point for workers and CLI. |
86−| `internal/entity` | **Database models** (GORM): Photo, File, Album, Label, Face, User, Session, etc. Contains fixtures for tests and migration helpers. |
87−| `internal/entity/query` | Database query helpers used by the API and core packages. |
88−| `internal/api` | **REST API handlers** (Gin): thin handlers that validate input, enforce ACL/auth, delegate to services. Annotated with Swagger comments. |
89−| `internal/server` | HTTP server setup, routing (Gin engine), WebDAV, static assets, middleware wiring. Routes are registered in `routes.go`. |
90−| `internal/config` | Application configuration: CLI flags, env vars, client config sent to the frontend. |
91−| `internal/workers` | Background workers: indexing scheduler, metadata sync, sharing, backup, vision jobs. |
92−| `internal/commands` | CLI command implementations (`github.com/urfave/cli/v2`). |
93−| `internal/auth` | Authentication: ACL (`auth/acl`), JWT (`auth/jwt`), OIDC (`auth/oidc`), session management. |
94−| `internal/form` | Request form/binding structs for the API layer. |
95−| `internal/meta` | Metadata extraction from EXIF, XMP, JSON sidecars. |
96−| `internal/ffmpeg` | FFmpeg/transcoding helpers. |
97−| `internal/thumb` | Thumbnail generation helpers. |
98−| `internal/ai` | AI/vision model integration (TensorFlow, ONNX). |
99−| `internal/service` | Services: maps geocoding, hub (membership), cluster, WebDAV client, CIDR helpers. |
100−| `internal/event` | Event bus for structured logging and audit events. |
101−| `pkg/` | Standalone, reusable packages: `fs`, `geo`, `media`, `txt`, `clean`, `rnd`, `i18n`, `http`, `time`, etc. No dependency on `internal/`. |
102−
103−**Request flow:** HTTP request → Gin middleware (auth, rate limiting) → `internal/api` handler → `internal/photoprism` or `internal/entity` → response.
104−
105−**Audit logging convention** (`event.AuditInfo/Warn/Err`): slices must follow the pattern **Who → What → Outcome**:
106−- Who: `ClientIP(c)` + actor context (`"session %s"`, `"user %s"`)
107−- What: resource constant + action segments
108−- Outcome: single token like `status.Succeeded`, `status.Failed`, `status.Denied`, `status.Error(err)`
109−
110−### Frontend (`frontend/`)
111−
112−Vue 3 app using the Options API and Vuetify 3.
113−
114−| Directory | Purpose |
115−|---------------------------|-------------------------------------------------------------------------------------------------|
116−| `frontend/src/model/` | Client-side models mirroring API responses (Photo, Album, File, User, etc.) |
117−| `frontend/src/app/` | App bootstrap, routing (`routes.js`), and the `$session` reactive singleton |
118−| `frontend/src/page/` | Page-level components |
119−| `frontend/src/component/` | Reusable UI components |
120−| `frontend/src/common/` | Shared utilities, the API client (`$api`), and reactive singletons (`$config`, `$view`, `$log`) |
121−| `frontend/src/locales/` | i18n translation files |
122−| `frontend/tests/` | Vitest unit tests + TestCafe acceptance tests |
123−
124−State management uses reactive singleton modules in `src/common/` and `src/app/`, not Vuex or Pinia. Frontend code-style, formatting, testing, translation, and Playwright rules live in `.claude/rules/frontend-rules.md`.
125−
126−### API Conventions
127−
128−- REST API v1 base path: `/api/v1/` (configured via `conf.BaseUri()`)
129−- Authentication: Bearer token (`Authorization` header) or `X-Auth-Token` header
130−- Pagination: `count`, `offset`, `limit` parameters (default 100, max 1000)
131−- After adding/changing API handlers, regenerate Swagger docs: `make fmt-go swag-fmt swag`
132−- New routes must be registered in `internal/server/routes.go`
133−
134−### Config & Flags
135−
136−Verify config option names before using them:
137−```bash
138−./photoprism --help
139−./photoprism show config-options
140−./photoprism show config-yaml
141−```
142−
143−### Verify Before Propagating
144−
145−Before promoting a claim from `CLAUDE.md`, `AGENTS.md`, a memory entry, or another spec into a new rule, spec, code comment, or commit message, verify it against the current code (grep imports, list directories, read the cited file). Stale documentation silently turns into stale rules and stale specs that future sessions will trust. When the claim names a package, function, file, or framework, the cost of one grep is much smaller than the cost of repeating an error across multiple files.
146−
147−### Detailed Rules
148−
149−Topic-specific conventions live under `.claude/rules/` and are loaded alongside this file:
150−
151−- `code-comments.md` — shared JS/Go doc comment rules (length cap, what to omit); referenced by both style files.
152−- `go-code-style.md`, `go-testing.md` — Go style, package boundaries, test patterns, fixtures.
153−- `frontend-rules.md` — JS/Vue code style, formatting, dependencies, tests, Playwright, translations.
154−- `commit-and-docs-style.md` — commit-message format, GitHub issue templates, spec heading style.
155−- `safety-and-security.md` — Git/data safety, destructive commands, file I/O and archive-extraction policies, HTTP download helpers.
156−- `api-and-config.md`, `cluster-operations.md`, `import-index-download.md`, `build-and-runtime.md`, `sources-of-truth.md` — domain-specific guidance.
109+- Include a dry-run or non-destructive variant if possible.
110+- Recommend creating/using backups before any reset/migrate.
157111
