From f7e63c4d5a91f3baed5c35016d87ed11f5a94bbd Mon Sep 17 00:00:00 2001 From: Matus Kasak Date: Wed, 25 Feb 2026 16:24:54 +0100 Subject: [PATCH 1/2] First version of agents.md --- docs/agents.md | 434 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 434 insertions(+) create mode 100644 docs/agents.md diff --git a/docs/agents.md b/docs/agents.md new file mode 100644 index 00000000000..7cd073a7437 --- /dev/null +++ b/docs/agents.md @@ -0,0 +1,434 @@ +# DSpace Angular – Agent & User Guide + +> **Audience**: AI coding agents (GitHub Copilot, Cursor, etc.) **and** humans who delegate issues to them. +> Covers the exact steps a user must do manually, the prompt to give the agent, what the agent must do, and hard-won lessons from real CI failures. + +--- + +## 1. Project Facts + +| Property | Value | +|----------|-------| +| Framework | Angular 15 + Angular Universal (SSR) | +| Language | TypeScript 4.8 | +| Package manager | **Yarn 1.x** — never use `npm` | +| Node.js | **18.x** (`nvm use 18`) — Node 20+ breaks `eslint-plugin-jsdoc` | +| Unit tests | Jasmine / Karma (~5 300 specs, ~3.5 min) | +| E2E tests | Cypress 13, Chrome headless | +| Main branch | `dtq-dev` | +| CI file | `.github/workflows/build.yml` | +| Repo | `dataquest-dev/dspace-angular` | + +--- + +## 2. User Checklist — What YOU Must Do Before the Agent Starts + +The agent cannot start Docker, install nvm, or open VS Code for you. Do these steps **once** per machine / session. + +### 2.1 One-time Setup + +1. Install **Docker Desktop** and start it. +2. Install **nvm** (or nvm-windows) and run: + ```bash + nvm install 18 + nvm use 18 + ``` +3. Install Yarn globally: `npm install -g yarn` +4. Clone the repo (if not done): + ```bash + git clone https://github.com/dataquest-dev/dspace-angular.git + cd dspace-angular + ``` + +### 2.2 Before Every Agent Session + +1. **Start the DSpace backend in Docker** (needed for e2e tests): + ```bash + docker compose -p ci -f docker/docker-compose-ci.yml up -d + docker compose -p ci -f docker/cli.yml -f docker/cli.assetstore.yml run --rm dspace-cli + ``` + Wait until `docker container ls` shows all containers healthy. + Verify: `curl http://localhost:8080/server/api/core/sites` returns JSON. + +2. **Ensure correct Node version** — `node --version` must say `v18.x`. + +3. **Set the heap size** (prevents OOM on build): + - PowerShell: `$env:NODE_OPTIONS='--max-old-space-size=4096'` + - Bash: `export NODE_OPTIONS='--max-old-space-size=4096'` + +4. **Install dependencies**: + ```bash + yarn install --frozen-lockfile + ``` + If Cypress download fails: `CYPRESS_INSTALL_BINARY=0 yarn install --frozen-lockfile` + +5. **Open the project in VS Code** (or your editor). + +6. **Create a feature branch**: + ```bash + git checkout dtq-dev && git pull + git checkout -b ufal/ + ``` + +### 2.3 Giving the Issue to the Agent + +Paste the agent a prompt like this (adapt the issue URL and description): + +> Here is the issue: `` +> Here is the agent guide: `docs/agents.md` +> +> Please read the guide first, then implement the fix, and iterate through **every CI step** +> (lint → circ-deps → build → unit tests → e2e tests) until all pass. +> Only then commit and push to the branch `ufal/`. +> If e2e tests fail on known pre-existing issues, that is acceptable — see the guide. + +That's it. The rest is the agent's job. + +--- + +## 3. The CI Pipeline (`build.yml`) + +Every PR triggers CI on Node 18.x and 20.x. **All steps must pass.** + +| # | Step | Command | Time | +|---|------|---------|------| +| 1 | Install | `yarn install --frozen-lockfile` | ~2 min | +| 2 | Lint | `yarn run lint --quiet` | ~76 sec | +| 3 | Circular deps | `yarn run check-circ-deps` | ~34 sec | +| 4 | Build (browser + server) | `yarn run build:prod` | ~6.5 min | +| 5 | Unit tests | `yarn run test:headless` | ~3.5 min | +| 6 | Docker backend up | `docker compose -f docker/docker-compose-ci.yml up -d` + assetstore | ~3 min | +| 7 | E2E tests | `yarn run serve:ssr` + Cypress via `cypress-io/github-action` | ~5 min | +| 8 | SSR verification | `wget` + `grep` on 10 entity pages (Home, Community, Collection, Publication, Person, Project, OrgUnit, Journal, Journal Volume, Journal Issue) | ~1 min | +| 9 | HTTP status codes | 301 `/handle/*`, 403, 404, 500 | ~30 sec | + +--- + +## 4. Agent Workflow — Step-by-Step Iteration + +### ⚠️ RULE: Do NOT commit or push until steps 1–5 all pass. Steps 6–7 if Docker backend is available. + +``` +FOR EACH step below: + 1. Run the command + 2. If it FAILS → fix the code → rerun THAT SAME step + 3. Only proceed to the next step when current one is green +``` + +### Step 1 — Install Dependencies +```bash +yarn install --frozen-lockfile +``` + +### Step 2 — Lint +```bash +yarn run lint --quiet +``` +Must exit with code 0 and print "All files pass linting." + +### Step 3 — Circular Dependencies +```bash +yarn run check-circ-deps +``` +Must print "✔ No circular dependency found!" + +**⚠️ PowerShell trap**: The underlying `madge --exclude` regex contains `|` pipe characters. PowerShell interprets `|` as a pipeline operator even inside quotes. Use the stop-parsing token: +```powershell +npx --% madge --exclude "(bitstream|bundle|collection|config-submission-form|eperson|item|version)\.model\.ts$" --circular --extensions ts ./ +``` + +### Step 4 — Production Build +```bash +yarn run build:prod +``` +Takes ~6.5 min. Run as a background process and poll for completion. +Must produce **two** successful bundles: browser + server. Ignore warnings about unused theme components and CommonJS dependencies — these are pre-existing. + +### Step 5 — Unit Tests +```bash +yarn run test:headless +``` +Expect ~5 300 specs, 0 failures. If a test fails, read the error, fix the code or test, rerun. + +Run a single test file: +```bash +yarn run test:headless --include='**/path/to/component.spec.ts' +``` + +### Step 6 — E2E Tests (requires Docker backend) + +Start the SSR server first (if not already running): +```bash +yarn run serve:ssr & # background +# Wait for http://localhost:4000 to respond +``` + +Run safe public-page specs (no login, no specific test data required): +```bash +npx cypress run --spec "cypress/e2e/footer.cy.ts,cypress/e2e/header.cy.ts,cypress/e2e/pagenotfound.cy.ts,cypress/e2e/browse-by-title.cy.ts,cypress/e2e/browse-by-author.cy.ts,cypress/e2e/browse-by-subject.cy.ts,cypress/e2e/community-list.cy.ts,cypress/e2e/search-page.cy.ts,cypress/e2e/feedback.cy.ts,cypress/e2e/browse-by-dateissued.cy.ts" --browser chrome +``` + +On Windows PowerShell, set the base URL first: +```powershell +$env:CYPRESS_BASE_URL="http://localhost:4000" +npx cypress run --spec "cypress/e2e/footer.cy.ts,..." --browser chrome +``` + +### Step 7 — Commit & Push (only after all green) + +```bash +git add # NEVER add config/config.yml or .env.* files +git commit -m "fix: " +git push origin ufal/ +``` + +--- + +## 5. E2E Test Categories & What to Run + +| Category | Spec files | Requires | +|----------|-----------|----------| +| **Public pages** (always safe) | `footer`, `header`, `pagenotfound`, `browse-by-*`, `community-list`, `search-page`, `feedback` | Frontend only | +| **Data-dependent** | `collection-page`, `community-page`, `item-page` | Backend + Demo Entities assetstore | +| **Login-required** | `submission*`, `admin-*`, `my-dspace`, `profile-page`, `handle-page`, `health-page`, `tombstone`, `system-wide-alert` | Backend + Demo Entities + valid credentials | +| **No active tests** | `homepage`, `homepage-statistics`, `search-navbar`, `login-modal` | N/A | + +### Cypress Config + +- Config: `cypress.config.ts` +- Specs: `cypress/e2e/*.cy.ts` +- Default base URL: `http://localhost:4000` (override with `CYPRESS_BASE_URL`) +- Retries: 2 in run mode, 0 in open mode +- Test data: [Demo Entities Data set](https://github.com/DSpace-Labs/AIP-Files/releases/tag/demo-entities-data) + +### Key Test Variables (from `cypress.config.ts`) + +| Variable | Value | +|----------|-------| +| `DSPACE_TEST_ADMIN_USER` | `dspacedemo+admin@gmail.com` | +| `DSPACE_TEST_ADMIN_PASSWORD` | `dspace` | +| `DSPACE_TEST_COMMUNITY` | `0958c910-2037-42a9-81c7-dca80e3892b4` | +| `DSPACE_TEST_COLLECTION` | `282164f5-d325-4740-8dd1-fa4d6d3e7200` | +| `DSPACE_TEST_ENTITY_PUBLICATION` | `6160810f-1e53-40db-81ef-f6621a727398` | + +--- + +## 6. Known Pre-existing E2E Failures (Not Your Bug) + +Before panicking about a red test, check this list: + +| Symptom | Affected Specs | Root Cause | Action | +|---------|---------------|------------|--------| +| `cy.get('.discojuice_close').click()` fails — element is `display: none` | All login-dependent tests | DiscoJuice popup is hidden in Docker env | **Skip** — pre-existing | +| `cy.wait('@viewevent')` timeout | `collection-page.cy.ts` | Matomo/statistics not configured in Docker | **Skip** — pre-existing | +| Entity redirect fails | `item-page.cy.ts` | Backend entity routing not configured | **Skip** — pre-existing | +| `link-in-text-block` a11y violation | `privacy.cy.ts`, `end-user-agreement.cy.ts` | CSS link styling issue | **Skip** — pre-existing | + +**Rule**: Only fix failures that YOUR changes caused. If a test was already failing on `dtq-dev`, leave it alone. + +--- + +## 7. Hard-Won Lessons (Pitfalls & Traps) + +These come from real agent sessions. Read them before writing code. + +### 7.1 Angular Template Binding + +❌ **WRONG** — interpolation inside `aria-*` / `attr.*`: +```html +
+``` +Angular will throw `Can't bind to 'aria-labelledby' since it isn't a known property` at build time. + +✅ **CORRECT** — property binding: +```html +
+``` + +This applies to **all** `aria-*` and custom HTML attributes. Always use `[attr.X]="expression"` instead of `X="{{ interpolation }}"` for non-standard attributes. + +### 7.2 Dynamic HTML IDs Must Be Valid + +HTML `id` attributes must not contain whitespace or special characters. If an ID is built from dynamic data (e.g., bundle names, file names, user input), **sanitize it**: + +```typescript +sanitizedName = rawName.replace(/\s+/g, ''); +``` + +Then use `sanitizedName` in the template `id` attribute. Never trust that a service will return a "safe" string for an HTML ID. + +### 7.3 Conditional `aria-describedby` + +If a `