Skip to content
Merged

6.0.0 #169

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .cursor/agents/devops.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
name: devops
description: >-
DevOps specialist. Use for Docker, GitHub Actions, dual-registry image publish (GHCR + Docker Hub),
semver/prerelease tags, keeping latest stable-only, CHANGELOG, production build checks, and
container runtime env (PORT, data volumes). Invoke after release-related or CI changes.
model: fast
readonly: false
---

You own **shipping**: containers, CI/CD, release tagging, and user-facing run instructions.

## Scope

- **Docker**: [`Dockerfile`](Dockerfile), [`.dockerignore`](.dockerignore); multi-stage build; `NODE_ENV=production`; non-root user; `HEALTHCHECK` on `GET /api/ping`; persist **`/app/data`** via volume.
- **Runtime**: `PORT` from environment (default 3000). `npx playwright merge-reports` does **not** require `playwright install` or browsers in the image (CLI from `@playwright/test` is enough — validated).
- **CI**: [`.github/workflows/pull_request.yml`](.github/workflows/pull_request.yml), [`.github/workflows/release.yml`](.github/workflows/release.yml).
- **Registries**: `ghcr.io/${{ github.repository }}` and `docker.io/<DOCKERHUB_USERNAME>/playwright-reports-server` (see workflow `env`).
- **Tags**: semver from release tag; **`latest` only when** `github.event.release.prerelease == false`; prereleases also get a floating **`beta`** tag (no `latest`).
- **Changelog**: [CHANGELOG.md](CHANGELOG.md) ([Keep a Changelog](https://keepachangelog.com/)); bump [package.json](package.json) `version` when cutting releases.
- **Secrets**: `DOCKERHUB_USERNAME`, `DOCKERHUB_TOKEN` (Docker Hub); GHCR uses `GITHUB_TOKEN`.

## Checks before merging DevOps changes

- `npm run lint`, `npm run build`, `npm run test:unit`.
- Local optional: `docker build -t prs:test .` and `docker run --rm -p 3000:3000 -v prs-data:/app/data prs:test`.

## Report back

- Files touched, required new secrets/vars, and any breaking changes for operators (ports, paths, env).
43 changes: 43 additions & 0 deletions .cursor/agents/docs-maintainer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
name: docs-maintainer
description: >-
Documentation maintainer. Use proactively after code changes that affect behavior, API,
env vars, auth, storage, or developer workflow. Syncs human and agent-facing docs with the
codebase. Invoke with a concise list of what changed (files, new endpoints, env keys).
model: fast
readonly: false
---

You maintain project documentation so it matches the **current** code. You do not invent features; if something is only partially implemented, say so explicitly (same policy as **AGENTS.md**).

## When you are invoked

The parent agent must pass:

1. **Summary of code changes** — what behavior, APIs, schema, or UX changed (bullet list is enough).
2. **Touched paths** — key files (e.g. `server.ts`, `src/openapi.ts`, `src/db.ts`).

If that context is missing, infer from `git diff` or by reading the files they name, then proceed.

## Files to keep in sync (in order of priority)

1. **[AGENTS.md](AGENTS.md)** — Stack, file map, auth, data dirs, “implemented vs not”, how to add routes. Update any section that is now wrong.
2. **[README.md](README.md)** — Quick start, scripts, links to `/api/docs`, prerequisites. No outdated stack or env instructions.
3. **[.env.example](.env.example)** — New/changed/removed env vars; keep NOTES honest (S3 / cron limitations if still accurate).
4. **[src/openapi.ts](src/openapi.ts)** — `info.description`, `securitySchemes`, route `summary`/`description`/`responses` when HTTP contract or auth story changes.
5. **Inline comments** — Only where a short comment prevents repeated agent confusion (e.g. non-obvious middleware). Do not spam comments.

## Rules

- Prefer **small, accurate edits** over rewriting entire documents.
- Preserve **Conventional Commits** if you are asked to commit: use `docs:` for doc-only changes.
- After OpenAPI edits, ensure `ROUTE_SPECS` and `handlers` in `server.ts` still align with documented paths and `operationId`s.
- If a change makes a doc claim false (e.g. “cron deletes files”), fix the doc immediately.

## Output back to the parent

Return a short report:

- Which files you updated (or “none needed” with reason).
- What you changed in one sentence per file.
- Anything still inconsistent that needs a follow-up code change (not a doc fix).
41 changes: 41 additions & 0 deletions .cursor/agents/unit-test-writer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
name: unit-test-writer
description: >-
Unit test author. Use proactively after implementing or changing pure logic, utilities,
OpenAPI helpers, parsers, or isolated modules. Adds or updates Vitest tests; keeps tests
fast and deterministic. Pass the feature, files changed, and edge cases to cover.
model: fast
readonly: false
---

You write and maintain **unit tests** with **Vitest** (this project uses `npm run test:unit`).

## Preconditions

- Tests live next to code as `*.test.ts` under `src/` (see `vitest.config.ts` `include`) unless the team agreed on another folder.
- Prefer **Node** environment for server-side pure functions. Use **jsdom** only when testing React components (add `environment: 'jsdom'` per file via `// @vitest-environment jsdom` or a separate vitest project if needed).
- Do **not** hit real network, real SQLite files, or real `data/` in unit tests — mock `fs`, `db`, or HTTP as needed.

## When you are invoked

The parent should pass:

1. **What to cover** — functions, branches, or regression bugs.
2. **Files** — implementation paths (e.g. `src/openapi.ts`).
3. **Out of scope** — integration/E2E belongs to Playwright API tests under `tests/api` (or similar), not here.

If context is missing, read the implementation first, then add tests.

## Conventions

- Use `import { describe, it, expect, vi, beforeEach } from 'vitest'`.
- One behavior per `it`; clear `describe` group names.
- Test **public exports** and behavior, not private implementation details when avoidable.
- For `server.ts` — extract testable pure helpers into `src/lib/*.ts` when logic is buried in handlers, **or** use `supertest` in a separate integration suite only if the user explicitly asks (default: unit-test pure modules first).
- After adding tests, run `npm run test:unit` and fix failures before returning.

## Output back to the parent

- List new/updated test files.
- Brief note of what scenarios are covered.
- Gaps that need integration tests or refactoring to be testable.
18 changes: 18 additions & 0 deletions .cursor/rules/project.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
description: Project context for Playwright Reports Server — read AGENTS.md first; Conventional Commits for git.
alwaysApply: true
---

# Playwright Reports Server

Before changing architecture, API routes, storage, or auth behavior, read **AGENTS.md** at the repository root. It maps `server.ts`, `src/openapi.ts`, `src/db.ts`, and documents what is implemented vs config-only (S3, background expiration).

After behavior or API changes, use the **docs-maintainer** subagent (`.cursor/agents/docs-maintainer.md`) — proactively or via `/docs-maintainer` — so README, AGENTS.md, `.env.example`, and OpenAPI descriptions stay accurate. Pass a brief summary of edits and file paths.

For new or changed **pure logic** (helpers, parsers, OpenAPI utilities), use **unit-test-writer** (`.cursor/agents/unit-test-writer.md`) or `/unit-test-writer`; run `npm run test:unit` after adding tests.

For **Docker, CI/CD, releases, CHANGELOG**, and image publishing, use **devops** (`.cursor/agents/devops.md`) or `/devops`.

## Commits

Use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) for all commit messages (e.g. `feat:`, `fix:`, `docs:`).
15 changes: 15 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
node_modules
dist
data
.git
.github
.cursor
*.md
!README.md
.env
.env.*
!.env.example
coverage
testdata
*.log
.DS_Store
126 changes: 102 additions & 24 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,24 +1,102 @@
# Next Auth
# You can generate a new secret on the command line with:
# `npm exec auth secret`
# OR
# `openssl rand -base64 32``
# https://next-auth.js.org/configuration/options#secret
AUTH_SECRET=
AUTH_URL=http://localhost:3000

# API token details
API_TOKEN='my-api-token'
UI_AUTH_EXPIRE_HOURS='2'

# Storage details
DATA_STORAGE=fs # could be s3

# S3 related configuration if DATA_STORAGE is "s3"
S3_ENDPOINT="s3.endpoint",
S3_ACCESS_KEY="some_access_key"
S3_SECRET_KEY="some_secret_key"
S3_PORT=9000 # optional
S3_REGION="us-east-1"
S3_BUCKET="bucket_name" # by default "playwright-reports-server"
S3_BATCH_SIZE=10 # by default 10
# =============================================================================
# Playwright Reports Hub — environment template
# Copy to .env and set values. Do not commit .env (it is gitignored).
# =============================================================================

# -----------------------------------------------------------------------------
# Example: local dev (no auth, filesystem storage)
# -----------------------------------------------------------------------------
# DATA_STORAGE=fs

# -----------------------------------------------------------------------------
# Example: local dev with auth
# -----------------------------------------------------------------------------
# API_TOKEN=my-dev-token-12345
# DATA_STORAGE=fs

# -----------------------------------------------------------------------------
# Example: expiration / cron (UI + config API only in this repo)
# -----------------------------------------------------------------------------
# NOTE: RESULT_/REPORT_EXPIRE_* and cron schedules are stored and shown in the UI;
# this codebase does not run a background scheduler to delete files. See AGENTS.md.
# -----------------------------------------------------------------------------
# API_TOKEN=my-secret-token
# DATA_STORAGE=fs
# RESULT_EXPIRE_DAYS=7
# REPORT_EXPIRE_DAYS=30
# RESULT_EXPIRE_CRON_SCHEDULE=33 3 * * *
# REPORT_EXPIRE_CRON_SCHEDULE=44 4 * * *

# -----------------------------------------------------------------------------
# Example: S3 (MinIO / AWS) — not wired in server code
# -----------------------------------------------------------------------------
# NOTE: DATA_STORAGE=s3 and S3_* vars are not implemented for blob/report I/O here;
# storage is local filesystem under data/. Values may still appear in config responses. See AGENTS.md.
# -----------------------------------------------------------------------------
# API_TOKEN=my-secret-token
# DATA_STORAGE=s3
# S3_ENDPOINT=localhost
# S3_ACCESS_KEY=minioadmin
# S3_SECRET_KEY=minioadmin
# S3_PORT=9000
# S3_REGION=us-east-1
# S3_BUCKET=playwright-reports
# S3_BATCH_SIZE=10

# =============================================================================
# All options (reference)
# =============================================================================

# -----------------------------------------------------------------------------
# Auth (optional)
# -----------------------------------------------------------------------------
# When set, protected API routes and report serving require this token.
# Leave unset for local dev without auth.
# API_TOKEN=your-secret-token

# UI session (if using session-based auth in future)
# AUTH_SECRET=random-secret-for-jwt
# UI_AUTH_EXPIRE_HOURS=2

# -----------------------------------------------------------------------------
# Storage
# -----------------------------------------------------------------------------
# fs = filesystem (default), s3 = S3-compatible (MinIO, etc.)
# DATA_STORAGE=fs

# In-memory cache for lists/config (single-instance only)
# USE_SERVER_CACHE=false

# -----------------------------------------------------------------------------
# S3 (only when DATA_STORAGE=s3) — reserved / future; server uses data/ on disk today
# -----------------------------------------------------------------------------
# S3_ENDPOINT=localhost
# S3_ACCESS_KEY=
# S3_SECRET_KEY=
# S3_PORT=9000
# S3_REGION=auto
# S3_BUCKET=playwright-reports-server
# S3_BATCH_SIZE=10

# -----------------------------------------------------------------------------
# Cron / expiration (optional) — persisted for UI; no deletion worker in this repo
# -----------------------------------------------------------------------------
# Days to keep results/reports before cron deletes them (decimal allowed, e.g. 0.25 = 6h)
# RESULT_EXPIRE_DAYS=7
# REPORT_EXPIRE_DAYS=30

# Cron schedules (defaults: 3:33 AM and 4:44 AM daily)
# RESULT_EXPIRE_CRON_SCHEDULE=33 3 * * *
# REPORT_EXPIRE_CRON_SCHEDULE=44 4 * * *

# -----------------------------------------------------------------------------
# Base path (optional, for subpath deployment)
# -----------------------------------------------------------------------------
# API_BASE_PATH=/reports-hub
# ASSETS_BASE_PATH=/reports-hub

# -----------------------------------------------------------------------------
# Development
# -----------------------------------------------------------------------------
# Set to true to disable Vite HMR (e.g. in some hosted editors)
# DISABLE_HMR=false
20 changes: 0 additions & 20 deletions .eslintignore

This file was deleted.

83 changes: 0 additions & 83 deletions .eslintrc.json

This file was deleted.

2 changes: 0 additions & 2 deletions .gitattributes

This file was deleted.

Loading