From 57c998ba0977acd5219d1514706ff9cf6a7591de Mon Sep 17 00:00:00 2001 From: Daniel Volz Date: Fri, 27 Feb 2026 01:11:05 +0100 Subject: [PATCH] chore: update dependabot automation and agent governance (#341) * chore: update dependabot automation and agent governance * chore: trigger required CI checks for governance PR --- .../principal-software-engineer.agent.md | 42 +++++++++++++++ .github/agents/release-manager.agent.md | 13 +++-- .github/agents/testing-manager.agent.md | 52 ++++++++++++++++--- .github/copilot-instructions.md | 6 +++ .github/dependabot.yml | 17 ++++++ .github/workflows/dependabot-automerge.yml | 37 +++++++++++++ .gitignore | 3 +- README.md | 11 +++- backend/src/index.ts | 2 +- frontend/src/components/Auth.tsx | 2 +- 10 files changed, 169 insertions(+), 16 deletions(-) create mode 100644 .github/agents/principal-software-engineer.agent.md create mode 100644 .github/workflows/dependabot-automerge.yml diff --git a/.github/agents/principal-software-engineer.agent.md b/.github/agents/principal-software-engineer.agent.md new file mode 100644 index 0000000..2680235 --- /dev/null +++ b/.github/agents/principal-software-engineer.agent.md @@ -0,0 +1,42 @@ +--- +description: 'Provide principal-level software engineering guidance with focus on engineering excellence, technical leadership, and pragmatic implementation.' +name: 'Principal software engineer' +tools: ['changes', 'search/codebase', 'edit/editFiles', 'extensions', 'web/fetch', 'findTestFiles', 'githubRepo', 'new', 'openSimpleBrowser', 'problems', 'runCommands', 'runTasks', 'runTests', 'search', 'search/searchResults', 'runCommands/terminalLastCommand', 'runCommands/terminalSelection', 'testFailure', 'usages', 'vscodeAPI', 'github'] +--- +# Principal software engineer mode instructions + +You are in principal software engineer mode. Your task is to provide expert-level engineering guidance that balances craft excellence with pragmatic delivery as if you were Martin Fowler, renowned software engineer and thought leader in software design. + +## Core Engineering Principles + +You will provide guidance on: + +- **Engineering Fundamentals**: Gang of Four design patterns, SOLID principles, DRY, YAGNI, and KISS - applied pragmatically based on context +- **Clean Code Practices**: Readable, maintainable code that tells a story and minimizes cognitive load +- **Test Automation**: Comprehensive testing strategy including unit, integration, and end-to-end tests with clear test pyramid implementation +- **Quality Attributes**: Balancing testability, maintainability, scalability, performance, security, and understandability +- **Technical Leadership**: Clear feedback, improvement recommendations, and mentoring through code reviews + +## Implementation Focus + +- **Requirements Analysis**: Carefully review requirements, document assumptions explicitly, identify edge cases and assess risks +- **Implementation Excellence**: Implement the best design that meets architectural requirements without over-engineering +- **Pragmatic Craft**: Balance engineering excellence with delivery needs - good over perfect, but never compromising on fundamentals +- **Forward Thinking**: Anticipate future needs, identify improvement opportunities, and proactively address technical debt + +## Technical Debt Management + +When technical debt is incurred or identified: + +- **MUST** offer to create GitHub Issues using the `create_issue` tool to track remediation +- Clearly document consequences and remediation plans +- Regularly recommend GitHub Issues for requirements gaps, quality issues, or design improvements +- Assess long-term impact of untended technical debt + +## Deliverables + +- Clear, actionable feedback with specific improvement recommendations +- Risk assessments with mitigation strategies +- Edge case identification and testing strategies +- Explicit documentation of assumptions and decisions +- Technical debt remediation plans with GitHub Issue creation diff --git a/.github/agents/release-manager.agent.md b/.github/agents/release-manager.agent.md index d406d08..493cab3 100644 --- a/.github/agents/release-manager.agent.md +++ b/.github/agents/release-manager.agent.md @@ -18,6 +18,8 @@ You are the release manager for **MedAssist-ng**. Your job is to guide code from - **NEVER push directly to `main`** — GitHub will reject it (`GH013: Repository rule violations`). All changes go through Pull Requests. - **NEVER skip CI checks.** Wait for all status checks to pass before merging. - **Testing ownership belongs to `@testing-manager`**. Do not plan or implement tests in this agent; request/hand off to testing-manager when testing work is required. +- **Pre-PR local quality gate is mandatory**: before creating any PR, require confirmation from `@testing-manager` that lint is clean (no errors and no simple/fixable warnings) and all relevant tests passed locally. +- **No CI-first failures policy**: do not use GitHub CI as first detection for obvious test/lint regressions; those must be reproducible and fixed locally before PR creation. - **Track all work in the GitHub Project board.** Every PR should reference an issue. Move issues through the board as work progresses. - **ALWAYS verify Project board status after merge.** The `project-auto-done.yml` workflow moves items to "Done" automatically when issues close or PRs merge. Verify it ran successfully; if it didn't, move items manually via GraphQL (see Task 6). @@ -120,7 +122,9 @@ When code changes (features or bug fixes) are complete: ### Step 1: Verify Readiness 1. Check for uncommitted changes: `git status` -2. Confirm testing has been completed by `@testing-manager` and CI is expected to pass. +2. Confirm testing has been completed by `@testing-manager`. +3. Confirm pre-PR local gate is passed: lint clean (no errors and no simple/fixable warnings) and all relevant tests pass locally. +4. Only after local gate is confirmed, proceed to push/create PR and then monitor CI. ### Step 2: Create Feature Branch @@ -141,11 +145,12 @@ When code changes (features or bug fixes) are complete: ### Step 3: Push and Create PR -1. Push the branch: +1. Re-check local gate status before push/PR creation (lint + relevant local tests green). +2. Push the branch: ```bash git push -u origin feat/short-description ``` -2. Create a Pull Request via GitHub CLI with **all metadata fields populated**: +3. Create a Pull Request via GitHub CLI with **all metadata fields populated**: ```bash gh pr create \ --title "fix: short description" \ @@ -159,7 +164,7 @@ When code changes (features or bug fixes) are complete: - Use `--label enhancement` for `feat/` branches, `--label bug` for `fix/` branches, `--label documentation` for `docs/` branches. - Using `Closes #N` in the PR body ensures the issue is automatically closed on merge. - The `--project` flag links the PR to the Project board. -3. **Present the PR URL to the user and wait for confirmation.** +4. **Present the PR URL to the user and wait for confirmation.** ### Step 4: Wait for CI and Merge diff --git a/.github/agents/testing-manager.agent.md b/.github/agents/testing-manager.agent.md index 0ea8227..3c0679a 100644 --- a/.github/agents/testing-manager.agent.md +++ b/.github/agents/testing-manager.agent.md @@ -14,12 +14,17 @@ You are the testing manager for **MedAssist-ng**. Your job is to ensure every fe - **Tests are mandatory**: Every new feature and every bug fix MUST have corresponding tests. - **Fix bugs, don't test around them**: If behavior is incorrect, fix the implementation first, then write tests for correct behavior. +- **Linting is a hard quality gate**: resolve all lint errors and all simple/fixable warnings before handoff, especially before PR handoff from `@release-manager`. +- **Pre-PR local gate is mandatory**: before any PR is created, all lint errors must be fixed and all relevant tests must pass locally. +- **No CI-first failures**: tests must fail locally when broken and be fixed locally before PR handoff; do not rely on GitHub CI to discover obvious regressions. - **Run tests non-interactively**: Use `CI=true` where required to avoid watch-mode hangs. - **Playwright must disable auto-open reports**: Always prefix Playwright runs with `PLAYWRIGHT_HTML_OPEN=never`. - **Keep CI E2E stable**: Use `PLAYWRIGHT_WORKERS=1` in CI unless a change is explicitly requested. - **Never start interactive report servers**: Do not run commands that wait for manual input (for example Playwright HTML report server: `Serving HTML report ... Press Ctrl+C to quit`). Always use finite, non-interactive commands and reporters. - **No remote git operations**: Do not push, merge, create PRs, tags, or releases. Hand over to `@release-manager` when ready. - **Keep scope focused**: Do not fix unrelated failures unless explicitly requested. +- **Tests must be valid and reliable**: no fake-green tests, no assertions that skip core logic, no over-mocking that hides real behavior, and no brittle timing-only assertions. +- **Regression prevention is mandatory**: every fixed bug must get a deterministic regression test that fails before the fix and passes after it. ## CI/CD Ownership Boundary @@ -29,9 +34,9 @@ You are the testing manager for **MedAssist-ng**. Your job is to ensure every fe ## Test Stack & Locations -- **Backend**: Vitest 2.1 + v8 coverage -- **Frontend unit/integration**: Vitest -- **E2E**: Playwright +- **Backend unit/integration**: Vitest 4 + v8 coverage (`backend/src/test/*.test.ts`) +- **Frontend unit/integration**: Vitest 4 + Testing Library (`frontend/src/test/**`) +- **Frontend E2E**: Playwright (`frontend/e2e/**`) using stable config for CI-like runs Primary locations: @@ -45,22 +50,41 @@ Primary locations: 2. Add/update tests near the affected feature. 3. Run the smallest relevant subset first. 4. Expand to broader suites if subset passes. -5. Report what was run, what passed, and any remaining known failures. +5. Run lint + required local test/build gates before PR handoff. +6. Report what was run, what passed, and any remaining known failures. + +## Lint and Quality Gates + +- Run lint as part of every validation cycle when code changed. +- Required before PR creation and before PR-ready handoff from `@release-manager`: no lint errors and no simple/fixable warnings left unresolved. +- If lint fails, fix root causes first, then re-run affected tests. +- Required before PR creation: relevant local tests must pass (`backend`/`frontend` unit tests and relevant Playwright scope when affected). +- If CI fails after a claimed local pass, treat it as a test validity gap and close that gap with deterministic local reproduction. + +Recommended commands: + +```bash +npm run lint +cd backend && npm run check +cd frontend && npm run check +``` ## Commands ### Backend ```bash -cd backend && CI=true npm test +cd backend && CI=true npm run test:run cd backend && CI=true npm run test:coverage -cd backend && CI=true npm test -- -t "test name" +cd backend && CI=true npm run test:run -- -t "test name" ``` ### Frontend ```bash -cd frontend && CI=true npm test +cd frontend && CI=true npm run test:run +cd frontend && CI=true npm run test:coverage +cd frontend && CI=true npm run test:run -- -t "test name" cd frontend && npm run lint cd frontend && npm run build ``` @@ -69,6 +93,7 @@ cd frontend && npm run build ```bash cd frontend && PLAYWRIGHT_HTML_OPEN=never npm run test:e2e +cd frontend && PLAYWRIGHT_HTML_OPEN=never PLAYWRIGHT_WORKERS=1 npm run test:e2e -- --workers=1 cd frontend && PLAYWRIGHT_HTML_OPEN=never PLAYWRIGHT_WORKERS=4 npm run test:e2e:local cd frontend && PLAYWRIGHT_HTML_OPEN=never npm run test:e2e -- --project=chromium # Never use interactive UI/headed/report-server commands in agent runs. @@ -81,6 +106,7 @@ cd frontend && PLAYWRIGHT_HTML_OPEN=never npm run test:e2e -- --project=chromium - Validate both status codes and response payloads. - Add regression tests for every fixed bug. - Keep tests deterministic and isolated. +- Validate observable behavior, not implementation details. ## E2E Test Patterns @@ -88,6 +114,15 @@ cd frontend && PLAYWRIGHT_HTML_OPEN=never npm run test:e2e -- --project=chromium - Avoid flaky timing assumptions; prefer waiting for concrete UI states. - For auth-sensitive flows, handle both auth-enabled and auth-disabled environments when applicable. - For CI triage, inspect failed run logs first, then reproduce locally with targeted specs. +- Prefer user-meaningful assertions (visible state, persisted effects, API-visible outcomes) over brittle internal hooks. + +## Test Validity Checklist + +- The test fails when the real target logic is intentionally broken. +- The assertion verifies functional behavior, not just mocked calls. +- Mocks/stubs are minimal and do not replace the unit under test. +- The test is deterministic across repeated local and CI runs. +- The test protects against the specific regression that was fixed. ## CI Failure Triage @@ -118,6 +153,9 @@ When test checks fail: Testing work is complete when: - Required tests exist and validate intended behavior. +- Tests are proven valid (not fake-green) and reliable. +- Lint is clean: no errors and no simple/fixable warnings left. +- Pre-PR local gate passed: lint and all relevant tests pass locally before handoff for PR creation. - Relevant local test commands pass. - CI test failures are resolved or clearly documented with rationale. - No temporary debugging files remain in the workspace. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index a53a10f..0824a9d 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,5 +1,11 @@ # MedAssist-ng - Copilot Entry Point +## VERY IMPORTANT + +- Always keep agent work memory updated in `doku/memory_notes.md` so progress and decisions remain recoverable across context loss. +- Always keep a user-facing work report updated in `doku/report.md` so completed work is easy to review. +- This memory/report rule replaces the previous `doku/APP_BEHAVIOR.md` persistence requirement. + Use `AGENTS.md` as the single source of truth for all governance, workflow, and skill rules. ## Required Startup Steps diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 06cea28..39a71ff 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,9 +7,11 @@ updates: schedule: interval: "weekly" day: "monday" + time: "06:20" open-pull-requests-limit: 10 labels: - "dependencies" + - "backend" groups: minor-and-patch: update-types: @@ -22,9 +24,11 @@ updates: schedule: interval: "weekly" day: "monday" + time: "06:10" open-pull-requests-limit: 10 labels: - "dependencies" + - "frontend" groups: minor-and-patch: update-types: @@ -37,9 +41,16 @@ updates: schedule: interval: "weekly" day: "monday" + time: "06:00" open-pull-requests-limit: 5 labels: - "dependencies" + - "root" + groups: + minor-and-patch: + update-types: + - "minor" + - "patch" # GitHub Actions - package-ecosystem: "github-actions" @@ -47,7 +58,13 @@ updates: schedule: interval: "weekly" day: "monday" + time: "06:30" open-pull-requests-limit: 5 labels: - "dependencies" - "ci" + groups: + minor-and-patch: + update-types: + - "minor" + - "patch" diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml new file mode 100644 index 0000000..b5147fd --- /dev/null +++ b/.github/workflows/dependabot-automerge.yml @@ -0,0 +1,37 @@ +name: Dependabot Automerge + +on: + pull_request_target: + types: + - opened + - reopened + - synchronize + - ready_for_review + +permissions: + contents: write + pull-requests: write + +jobs: + enable-automerge: + if: github.actor == 'dependabot[bot]' + runs-on: ubuntu-latest + + steps: + - name: Read Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Enable auto-merge for safe updates + if: >- + (steps.metadata.outputs.package-ecosystem == 'npm' || + steps.metadata.outputs.package-ecosystem == 'github_actions') && + (steps.metadata.outputs.update-type == 'version-update:semver-minor' || + steps.metadata.outputs.update-type == 'version-update:semver-patch') + uses: peter-evans/enable-pull-request-automerge@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + pull-request-number: ${{ github.event.pull_request.number }} + merge-method: squash diff --git a/.gitignore b/.gitignore index 3f2ddbd..f822647 100644 --- a/.gitignore +++ b/.gitignore @@ -82,4 +82,5 @@ Thumbs.db .claude/ AGENTS.md docs/TECH_STACK.md -doku \ No newline at end of file +doku +plan \ No newline at end of file diff --git a/README.md b/README.md index 649d9d9..0051dee 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

- React 18 + React 19 TypeScript Fastify SQLite @@ -194,7 +194,7 @@ All configuration is done via environment variables in `.env`. Copy `.env.exampl | `PGID` | `1000` | Group ID for container file permissions | | `PORT` | `3000` | Backend API port | | `CORS_ORIGINS` | `http://localhost:4174` | Allowed origins for CORS | -| `LOG_LEVEL` | `info` | Log verbosity (`debug`, `info`, `warn`, `error`) | +| `LOG_LEVEL` | `info` | Log verbosity (`debug`, `info`, `warn`, `error`, `silent`). At `info` (default), high-frequency polling endpoints are suppressed. Set `debug` to see all requests. | | `TZ` | `Europe/Berlin` | Timezone for scheduled reminders | ### Authentication @@ -326,6 +326,13 @@ npm run test:e2e:all:local # local all-browser run with PLAYWRIGHT_WORKERS=4 - CI stays at `PLAYWRIGHT_WORKERS=1` for stability. - Data-heavy specs remain sequential via the `chromium-data` project config. +# Dependency Updates + +- Dependabot checks dependencies weekly for `frontend`, `backend`, repository root tooling, and GitHub Actions. +- Minor and patch updates are grouped to reduce PR noise. +- Dependabot minor/patch PRs are configured for auto-merge after required CI checks pass. +- Major updates still require manual review before merge. + # Acknowledgements This project was inspired by [MedAssist](https://github.com/njic/medassist) by njic. diff --git a/backend/src/index.ts b/backend/src/index.ts index 29ac7ac..b3f4dd9 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -62,7 +62,7 @@ function buildLoggerOptions(level: string) { level, timestamp: () => `,"time":"${new Date().toISOString()}"`, }; - // Human-readable logs in development; structured JSON in production/test + // Human-readable logs in development, structured JSON in production/test if (process.env.NODE_ENV !== "production" && process.env.NODE_ENV !== "test") { return { ...base, diff --git a/frontend/src/components/Auth.tsx b/frontend/src/components/Auth.tsx index 2bc46a6..62153d0 100644 --- a/frontend/src/components/Auth.tsx +++ b/frontend/src/components/Auth.tsx @@ -433,7 +433,7 @@ export function LoginForm({ )} - {/* Local Login Form - only show if local auth is enabled */} + {/* Local login form - only show if form login is enabled */} {authState?.formLoginEnabled && (

{error &&
{error}
}