mirror of
https://github.com/photoprism/photoprism.git
synced 2026-07-17 16:49:04 +00:00
Claude: Align rules with AGENTS.md and fix test coverage placement
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
parent
8640dee635
commit
32f8bd9896
4 changed files with 37 additions and 5 deletions
|
|
@ -1,7 +1,7 @@
|
|||
## Cluster Operations
|
||||
|
||||
- Keep bootstrap code decoupled: avoid importing `internal/service/cluster/node/*` from `internal/config` or the cluster root, let nodes talk to the Portal over HTTP(S), and rely on constants from `internal/service/cluster/const.go`.
|
||||
- Bootstrap refreshes node OAuth credentials on 401/403 responses (rotate secret + retry) and logs the refresh at info level.
|
||||
- Bootstrap refreshes node OAuth credentials on 401/403 responses (rotate secret + retry) and logs the refresh at info level. If the secret file cannot be written, the rotated value stays cached in memory so the current process can continue.
|
||||
- Portal validation now accepts HTTP advertise URLs only for loopback hosts or cluster-internal domains (`*.svc`, `*.cluster.local`, `*.internal`); everything else must use HTTPS.
|
||||
- Theme endpoint: `GET /api/v1/cluster/theme` streams a zip from `conf.ThemePath()`; only reinstall when `app.js` is missing and always use the header helpers in `pkg/http/header`.
|
||||
- Registration flow: send `rotate=true` only for MySQL/MariaDB nodes without credentials, treat 401/403/404 as terminal, include `ClientID` + `ClientSecret` when renaming an existing node, and persist only newly generated secrets or DB settings.
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
- Database/user names use UUID-based HMACs (`<prefix>d<hmac11>`, `<prefix>u<hmac11>` where the prefix defaults to `cluster_`).
|
||||
- `BuildDSN` accepts a `driver` but falls back to MySQL format with a warning when unsupported.
|
||||
- If Postgres provisioning is added, extend `BuildDSN` and `provisioner.DatabaseDriver` handling, add validations, and return `driver=postgres` consistently in API and CLI output.
|
||||
|
||||
### Sessions & Redaction
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,30 @@
|
|||
## Frontend Test Coverage
|
||||
|
||||
- New JavaScript functions, including helpers, should be tested whenever practical; update existing tests or add new ones as needed.
|
||||
- New Vue components should have component-test coverage, and existing component tests should be updated as needed when component behavior changes.
|
||||
|
||||
## Frontend Linting & Test Entry Points
|
||||
|
||||
- Use the lint and format scripts declared in `frontend/package.json`; all added JS, Vue, and frontend tests must follow those standards.
|
||||
- Frontend unit tests use Vitest. Common entry points: `make test-js`, `make vitest-watch`, `make vitest-coverage`.
|
||||
- Acceptance tests use the `acceptance-*` targets in the root `Makefile`.
|
||||
- For one-off TestCafe checks, keep startup and cleanup in the repository root: `make storage/acceptance`, `make acceptance-sqlite-restart`, `make wait-2`, then run the testcafe command from `frontend/`, then `make acceptance-sqlite-stop`.
|
||||
- If a command temporarily changes into `frontend/`, return to the repository root before running `make acceptance-sqlite-stop`.
|
||||
|
||||
## Frontend Test Gotchas
|
||||
|
||||
- Hidden-route UI checks under `/library/hidden` or `/portal/admin/hidden` require both `files.file_error` and `photos.photo_quality = -1`; `file_error` alone will not surface the row.
|
||||
|
||||
## Playwright MCP Usage
|
||||
|
||||
- Default endpoint is `http://localhost:2342/`; default login routes are `/library/login` for CE, Plus, and Pro, and `/portal/admin/login` for Portal.
|
||||
- Use the local compose admin credentials; if login fails, inspect the active compose environment.
|
||||
- Desktop sessions default to `1280x900`; mobile sessions should use the mobile Playwright server with `375x667`.
|
||||
- Close the browser tab after scripted interactions.
|
||||
- Prefer waits over sleeps, click only visible and enabled elements, and use role, label, or text selectors instead of brittle XPath selectors.
|
||||
- Keep screenshots small and reproducible: prefer JPEG, visible viewport, deterministic `.local/screenshots/<case>/<step>__<viewport>.jpg` names, and no large inline screenshots.
|
||||
- If `npx` fetches an MCP server at runtime, add `--yes` or preinstall it to avoid prompts.
|
||||
|
||||
## Frontend Focus Management
|
||||
|
||||
- Dialogs must follow the shared focus pattern documented in `frontend/src/common/README.md`.
|
||||
|
|
@ -16,8 +43,8 @@
|
|||
- HTML entrypoints live under `assets/templates/`; key files are `index.gohtml`, `app.gohtml`, `app.js.gohtml`, and `splash.gohtml`.
|
||||
- Browser check logic: `assets/static/js/browser-check.js` is included via `app.js.gohtml`; it performs capability checks before the main bundle executes.
|
||||
- OIDC login completion for the web UI is bridged through `assets/templates/auth.gohtml`, which writes the session into namespaced browser storage. Must stay aligned with `frontend/src/common/session.js`, `frontend/src/common/storage.js`, and the login form toggle in `frontend/src/page/auth/login.vue`.
|
||||
- When touching frontend session bootstrap, verify that `frontend/src/common/session.js` resolves `storageNamespace` from the real client config shape (`window.__CONFIG__` / `config.values`), not only from simplified mocks.
|
||||
- When touching frontend session bootstrap, verify that `frontend/src/common/session.js` resolves `storageNamespace` from the real client config shape (`window.__CONFIG__` / `config.values`), not only from simplified mocks. Include a focused test that would fail if session restore fell back to the `pp:root:` namespace.
|
||||
- Keep the script order in `app.js.gohtml` so `browser-check.js` loads before the bundle script. Do not add `defer` or `async` to the bundle tag unless you reintroduce a guarded loader.
|
||||
- The same loader partial is reused in private packages (`pro/assets/templates/index.gohtml`, `plus/assets/templates/index.gohtml`, `portal/assets/templates/index.gohtml`). Mirror updates when touching `app.js.gohtml`.
|
||||
- The same loader partial is reused in private packages (`pro/assets/templates/index.gohtml`, `plus/assets/templates/index.gohtml`, `portal/assets/templates/index.gohtml`). Whenever you change `app.js.gohtml` or bundle loading, verify those files still include the shared partial.
|
||||
- Splash styles: `frontend/src/css/splash.css`. Add new splash elements there for visual consistency across editions.
|
||||
- Browser baseline: Safari 13 / iOS 13 or current Chrome, Edge, or Firefox.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
## Go Test Coverage
|
||||
|
||||
- Every new Go function, including unexported helpers, must have focused test coverage in the corresponding `*_test.go` file; update existing tests or add new ones as needed.
|
||||
|
||||
## Go Testing Patterns
|
||||
|
||||
- Go tests live next to their sources (`path/to/pkg/<file>_test.go`); group related cases as `t.Run(...)` sub-tests to keep table-driven coverage readable. Use **PascalCase** for subtest names (e.g., `t.Run("Success", ...)`).
|
||||
|
|
@ -28,7 +32,7 @@
|
|||
- `PhotoFixtures.Get()` and similar helpers return value copies; when a test needs the database-backed row, re-query by UID/ID using helpers like `entity.FindPhoto(fixture)`.
|
||||
- When adding persistent fixtures, always obtain new IDs via `rnd.GenerateUID(...)` with the matching prefix (`entity.PhotoUID`, `entity.FileUID`, `entity.LabelUID`, …).
|
||||
- For database updates, prefer the `entity.Values` type alias over raw `map[string]interface{}`.
|
||||
- Generate identifiers with `rnd.GenerateUID(entity.ClientUID)` for OAuth client IDs and `rnd.UUIDv7()` for node UUIDs.
|
||||
- Generate identifiers with `rnd.GenerateUID(entity.ClientUID)` for OAuth client IDs and `rnd.UUIDv7()` for node UUIDs; treat `node.uuid` as required in responses.
|
||||
- When you need illustrative credentials (join tokens, client IDs/secrets, etc.), reuse the shared `Example*` constants (see `internal/service/cluster/examples.go`).
|
||||
|
||||
### CLI Testing Gotchas
|
||||
|
|
|
|||
|
|
@ -41,4 +41,4 @@ Harness env vars (supported by our tests):
|
|||
- Pipe method: PhotoPrism remux (ffmpeg) always embeds title/description/created.
|
||||
- File method: yt-dlp writes files; we pass `--postprocessor-args 'ffmpeg:-metadata creation_time=<RFC3339>'` so imports get `Created` even without local remux.
|
||||
- Default remux policy: `auto`; use `always` for the most complete metadata.
|
||||
- CLI defaults: `photoprism dl` now defaults to `--method pipe` and `--impersonate firefox`.
|
||||
- CLI defaults: `photoprism dl` now defaults to `--method pipe` and `--impersonate firefox`; pass `-i none` to disable impersonation.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue