feat: implement new feature for enhanced user experience

This commit is contained in:
2026-02-11 16:36:56 +00:00
parent 62f1906276
commit dc00d24899
75 changed files with 2456 additions and 35 deletions

View File

@@ -1,25 +1,25 @@
# Copilot Instructions
## Common Instructions
This workspace uses scoped instructions with YAML front matter in `.github/instructions/*.instructions.md`.
Keep this file minimal to avoid duplicate or conflicting guidance.
- Look in the problems tab for any errors or warnings in the code
- Follow the existing code style and conventions used in the project
- Write clear and concise comments where necessary to explain complex logic
- Ensure code is modular and reusable where possible
- Write unit tests for new functionality and ensure existing tests pass, but only if there is a configured testing framework
- Avoid introducing new dependencies unless absolutely necessary, but ask the user if there is a specific library they want to use
- If you are unsure about any requirements or details, ask the user for clarification before proceeding
- Respect a11y and localization best practices if applicable, optimize for WCAG AA standards
## Quick Reference
- **General workflow**: See `.github/instructions/general.instructions.md`
- **Frontend (Svelte)**: See `.github/instructions/frontend.instructions.md`
- **API Hooks (tibi-server)**: See `.github/instructions/api-hooks.instructions.md`
- **SSR/Caching**: See `.github/instructions/ssr.instructions.md`
- **Testing (Playwright)**: See `.github/instructions/testing.instructions.md`
## Toolchain
- See .env in root for project specific environment variables
- See Makefile for starting up the development environment with Docker
- If development environment is running, access the website at: https://${PROJECT_NAME}.code.testversion.online/ or ask the user for the correct URL
- See `.env` in root for project-specific environment variables
- See `Makefile` for starting up the development environment with Docker
- If development environment is running, access the website at: `https://${PROJECT_NAME}.code.testversion.online/` or ask the user for the correct URL
- You can also use Browser MCP, so ask user to connect if needed
- Esbuild is used, watching for changes in files to rebuild automatically
- To force a restart of the frontend build and dev-server run: `make restart-frontend`
- Backend is tibi-server configured in /api/ folder and also restarted if changes are detected in this folder
- To show last X lines of docker logs run: `make docker-logs-X` where X is the number
of lines you want to see
- To force a restart of the frontend build and dev-server run: `make docker-restart-frontend`
- Backend is tibi-server configured in `/api/` folder and also restarted if changes are detected in this folder
- To show last X lines of docker logs run: `make docker-logs-X` where X is the number of lines you want to see
- For a11y testing use the MCP a11y tools if available
- For testing run: `yarn test` (all), `yarn test:e2e`, `yarn test:api`, `yarn test:visual`

View File

@@ -0,0 +1,51 @@
---
name: API Hooks
description: tibi-server hook conventions and typing.
applyTo: "api/hooks/**"
---
# API Hooks (tibi-server)
- Wrap hook files in an IIFE: `;(function () { ... })()`.
- Always return a HookResponse type or throw a HookException type.
- Use inline type casting with `/** @type {TypeName} */ (value)` and typed collection entries from `types/global.d.ts`.
- Avoid `@ts-ignore`; use proper casting instead.
- Use `const` and `let` instead of `var`. The tibi-server runtime supports modern JS declarations.
## context.filter Go object quirk
`context.filter` is not a regular JS object but a Go object. Even when empty, it is **truthy**.
Always check with `Object.keys()`:
```js
const requestedFilter =
context.filter &&
typeof context.filter === "object" &&
!Array.isArray(context.filter) &&
Object.keys(context.filter).length > 0
? context.filter
: null
```
**Never** use `context.filter || null` it is always truthy and results in an empty filter object inside `$and`, which crashes the Go server.
## Single-item vs. list retrieval
For single-item retrieval (`GET /:collection/:id`), the Go server sets `_id` automatically from the URL parameter.
GET read hooks should therefore **not set their own `_id` filter** for `req.param("id")`;
instead, only add authorization filters (e.g. `{ userId: userId }`).
## HookResponse fields for GET hooks
- `filter` MongoDB filter (list retrieval only, or to restrict single-item retrieval)
- `selector` MongoDB projection (`{ fieldName: 0 }` to exclude, `{ fieldName: 1 }` to include)
- `offset`, `limit`, `sort` pagination/sorting
- `pipelineMod` function to manipulate the aggregation pipeline
## API Tests (Playwright)
- When creating or modifying collections/hooks: extend or create corresponding API tests in `tests/api/`.
- Test files live under `tests/api/` and use fixtures from `tests/api/fixtures.ts`.
- Helpers: `ensureTestUser()` (`tests/api/helpers/test-user.ts`), Admin API (`tests/api/helpers/admin-api.ts`), MailDev (`tests/api/helpers/maildev.ts`).
- After hook changes, run only the affected API tests: `npx playwright test tests/api/filename.spec.ts`.
- When tests fail, clarify whether the hook or the test needs adjustment coordinate with the user.

View File

@@ -0,0 +1,28 @@
---
name: Frontend
description: Svelte SPA structure and conventions.
applyTo: "frontend/src/**"
---
# Frontend
- SPA entry point is `frontend/src/index.ts`, main component is `frontend/src/App.svelte`.
- Component organization: `lib/` for utilities and stores, keep route components in a `routes/` folder when needed, `css/` for styles.
- Use PascalCase component names and export props at the top of the `<script>` tag; keep code/comments in English.
- SSR safety: guard browser-only code with `typeof window !== "undefined"`.
- API behavior: PUT responses return only changed fields; filter by id uses `_id`; API requests reject non-2xx with `{ response, data }` and error payload in `error.data.error`.
## i18n
- `svelte-i18n` is configured in `frontend/src/lib/i18n/index.ts` with lazy loading for locale files.
- Locale files live in `frontend/src/lib/i18n/locales/{lang}.json`.
- URL-based language routing: `/{lang}/...` (e.g. `/de/`, `/en/about`).
- Language utilities in `frontend/src/lib/i18n.ts`: `extractLanguageFromPath()`, `localizedPath()`, `getLanguageSwitchUrl()`.
- Use `$_("key")` from `svelte-i18n` for translations in components.
## E2E Tests (Playwright)
- When developing frontend features: extend or create corresponding E2E tests in `tests/e2e/`.
- Shared fixtures and helpers in `tests/e2e/fixtures.ts`: `waitForSpaReady(page)`, `navigateToRoute(page, path)`, `clickSpaLink(page, selector)`, `authedPage` fixture.
- After frontend changes, run only the affected E2E tests: `npx playwright test tests/e2e/filename.spec.ts` or `-g "test name"`.
- When tests fail, clarify whether the frontend or the test needs adjustment coordinate with the user.

View File

@@ -0,0 +1,38 @@
---
name: General
description: Workspace-wide guidance and workflows.
applyTo: "**/*"
---
# General
## Code Style & Conventions
- Look in the problems tab for any errors or warnings in the code
- Follow the existing code style and conventions used in the project
- Write clear and concise comments where necessary to explain complex logic
- Ensure code is modular and reusable where possible
- Avoid introducing new dependencies unless absolutely necessary, but ask the user if there is a specific library they want to use
- If you are unsure about any requirements or details, ask the user for clarification before proceeding
- Respect a11y and localization best practices if applicable, optimize for WCAG AA standards
## Development Workflow
- Default dev flow is Docker/Makefile: `make docker-up`, `make docker-start`, `make docker-logs`, `make docker-restart-frontend` (see Makefile).
- Local dev is secondary: `yarn dev` for watch, `yarn build` and `yarn build:server` for production builds (see package.json).
- Frontend code is automatically built by watcher and browser-sync; backend code is automatically built and reloaded by extension, so no manual restarts needed during development.
- Read `.env` for environment URLs and secrets.
- Keep `tibi-types/` read-only unless explicitly asked.
- `webserver/` is for staging/ops only; use BrowserSync/esbuild for day-to-day dev.
## API Access
- API access to collections uses the reverse proxy: `CODING_URL/api/<collection>` (e.g. `CODING_URL/api/content`).
- Auth via `Token` header with ADMIN_TOKEN from `api/config.yml.env`.
## Testing
- Write unit tests for new functionality and ensure existing tests pass.
- Playwright is configured for E2E, API, mobile, and visual regression tests.
- Run tests via `yarn test` (all), `yarn test:e2e`, `yarn test:api`, `yarn test:visual`.
- After code changes, run only affected spec files: `npx playwright test tests/e2e/filename.spec.ts`.

View File

@@ -0,0 +1,12 @@
---
name: SSR
description: Server-side rendering flow and caching.
applyTo: "api/hooks/ssr/**"
---
# SSR and Caching
- SSR request flow: `api/hooks/ssr/get_read.js` calls `api/hooks/lib/ssr-server.js` and injects `window.__SSR_CACHE__` used by `api/hooks/lib/ssr.js` on the client.
- SSR cache HTML is stored in the `ssr` collection.
- SSR builds output to `api/hooks/lib/app.server.js` via `yarn build:server`.
- SSR route validation is currently disabled and returns -1 in `api/hooks/config.js`; update this when enabling SSR per route.

View File

@@ -0,0 +1,41 @@
---
name: Testing
description: Playwright test conventions, fixtures, and visual regression.
applyTo: "tests/**"
---
# Testing
- Playwright for API tests (`tests/api/`), E2E tests (`tests/e2e/`), mobile tests (`tests/e2e-mobile/`), and Visual Regression tests (`tests/e2e-visual/`). Config in `playwright.config.ts`.
- Self-test after code changes: run only affected spec files (`npx playwright test tests/e2e/filename.spec.ts` or `-g "test name"`), not a full test suite run saves time.
- Always coordinate test adjustments with the user: do not fix broken tests to match buggy frontend or vice versa. When tests fail, first clarify whether the test or the code is wrong.
## BrowserSync Workaround
BrowserSync keeps a WebSocket open permanently, preventing `networkidle` and `load` from resolving. All fixture files override `page.goto()` and `page.reload()` to use `waitUntil: "domcontentloaded"` by default. Always use `domcontentloaded` for navigation waits.
## Fixtures & Helpers
- `tests/e2e/fixtures.ts` Shared fixtures (`authedPage`, `testUser`) and helpers (`waitForSpaReady`, `navigateToRoute`, `clickSpaLink`).
- `tests/e2e-visual/fixtures.ts` Visual test helpers (`waitForVisualReady`, `hideDynamicContent`, `prepareForScreenshot`, `expectScreenshot`, `getDynamicMasks`).
- `tests/e2e-mobile/fixtures.ts` Mobile helpers (`openHamburgerMenu`, `isMobileViewport`, `isTabletViewport`, `isBelowLg`).
- `tests/api/fixtures.ts` API fixtures (`api`, `authedApi`, `accessToken`).
- `tests/api/helpers/` API test utilities (`test-user.ts`, `admin-api.ts`, `maildev.ts`).
- `tests/fixtures/test-constants.ts` Central constants (`TEST_USER`, `ADMIN_TOKEN`, `API_BASE`).
## Visual Regression Tests
- Visual regression tests live in `tests/e2e-visual/` with separate Playwright projects (`visual-desktop`, `visual-iphonese`, `visual-ipad`).
- Run: `yarn test:visual`. Update baselines: `yarn test:visual:update`.
- Screenshots are stored in `tests/e2e-visual/__screenshots__/{projectName}/` and MUST be committed to the repo.
- Tolerance: `maxDiffPixelRatio: 0.02` (2%) for cross-OS/hardware rendering differences.
- Always call `prepareForScreenshot(page)` before `expectScreenshot()`.
- Use `waitForVisualReady(page)` instead of `waitForSpaReady()` it additionally waits for skeleton loaders and CSS settling.
- Dynamic content: `hideDynamicContent(page)` disables BrowserSync overlay and animations; `getDynamicMasks(page)` returns locators for non-deterministic elements.
- For AI review of screenshots, run `./scripts/export-visual-screenshots.sh`.
## API Tests
- API tests use `tests/api/fixtures.ts` with `api` (unauthenticated) and `authedApi` (with Bearer token) fixtures.
- Helpers: `ensureTestUser()` (`tests/api/helpers/test-user.ts`), Admin API (`tests/api/helpers/admin-api.ts`), MailDev (`tests/api/helpers/maildev.ts`).
- After hook changes, run only affected API tests: `npx playwright test tests/api/filename.spec.ts`.