No description
  • TypeScript 99.5%
  • Dockerfile 0.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Renovate Bot 8a869df5a7
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
chore(deps): update woodpeckerci/plugin-git docker tag to v2.10.1
2026-09-09 00:02:27 +00:00
.githooks feat(monitor): add Playwright repair monitoring 2026-08-22 11:16:36 +02:00
config feat: add Planity appointment availability monitoring 2026-09-04 21:05:32 +02:00
src Add web check page to monitor container 2026-09-04 21:32:52 +02:00
.dockerignore feat: schedule monitor sources in container 2026-09-04 20:18:12 +02:00
.gitattribues ci: configure Biome checks 2026-08-22 14:53:30 +02:00
.gitignore feat: schedule monitor sources in container 2026-09-04 20:18:12 +02:00
.woodpecker.yml chore(deps): update woodpeckerci/plugin-git docker tag to v2.10.1 2026-09-09 00:02:27 +00:00
biome.json ci: configure Biome checks 2026-08-22 14:53:30 +02:00
bun.lock chore(deps): lock file maintenance 2026-09-06 01:03:18 +00:00
docker-entrypoint.sh Add web check page to monitor container 2026-09-04 21:32:52 +02:00
Dockerfile chore(deps): update oven/bun docker tag to v1.4.2 2026-09-05 07:02:00 +00:00
package.json chore: upd deps 2026-09-05 07:47:36 +02:00
README.md Add web check page to monitor container 2026-09-04 21:32:52 +02:00
renovate.json feat: Enhance BIOS version tracking and notifications 2025-05-30 20:13:11 +02:00
sonar-project.properties feat: schedule monitor sources in container 2026-09-04 20:18:12 +02:00
tsconfig.json feat(monitor): add Playwright repair monitoring 2026-08-22 11:16:36 +02:00

nyyu monitor

The monitor checks configured driver and release sources. It can run a single check from the command line or schedule every source independently inside a long-running container.

Static monitor configuration is stored in config/monitor.json. It contains the S3 storage bucket and all monitored sources. Every source has a required five-field cron expression, evaluated in the Europe/Paris time zone. AWS and notification credentials remain environment variables.

The MiRom monitor uses kind: "mirom". Configure the phone and ROM variant with options.romPath, for example "klimt/roms-eea-stable"; the source can therefore monitor any phone supported by MiRom. The last stored version is used to select a matching incremental OTA when the page provides one; otherwise the available incremental OTA is used by default. The public notification link changes only the official bigota.d.miui.com hostname to bn.d.miui.com.

Run with Bun

bun install
bunx playwright install chromium
bun --env-file=.env src/main.ts

To check sources without AWS credentials, persistent snapshots, or outgoing notifications, use check mode. It prints the exact email subject and body as a preview only; no email or SMS is sent. Add --source to check one configured source:

bun run start -- --check --source xiaomi-15t-pro-eea

For a small browser UI, run the monitor in web mode and open the displayed URL:

bun run start -- --web --port 3000

The page's Check button runs a check-only scan. It does not write snapshots or send notifications; use the source selector to check one source.

The optional Cordon SAV scraper uses a headed Playwright browser. A headless server running that source directly must therefore provide an X display.

Planity availability monitor

kind: "planity" uses the same headed Playwright setup as Cordon SAV. Its configuration supplies the salon, exact service and employee, plus preferred days and hours; Planity credentials remain outside the JSON configuration:

PLANITY_EMAIL=you@example.com
PLANITY_PASSWORD=<password>

Bun expands $VARIABLE references in .env values. Escape each literal dollar sign in a Planity password as \$ (for example, PLANITY_PASSWORD='prefix\$literal') so the full value reaches the browser.

The bundled planity-le-baron-orvault source watches Gwendolyn's exact Shampoing + Coupe + Coiffage classique service. It reads the next matching appointment from Mes RDV, then considers only earlier slots. A preferred slot is Monday, Wednesday, or Friday from 12:00 through 14:00 inclusive, or from 17:00 onward. The earliest slot outside those preferences is included in the notification separately.

bun run start -- --check --source planity-le-baron-orvault

Check mode never writes S3 state, sends a notification, or books/moves an appointment. autoBookPreferred is configured as false; automatic booking is intentionally not implemented, and outside-preference slots are never booked.

The monitor stores the last result in the configured S3 bucket. Configure the existing notification API with:

NOTIFICATION_API_URL=https://api.nyyu.dev/notifications/send
NOTIFICATION_API_TOKEN=<same random secret configured in ng_api>

When a new update is detected, the monitor posts { "subject": "...", "email": "...", "sms": "..." } to that endpoint. The monitor uses the notification API exclusively; the API sends whichever channel fields are supplied and configured.

Run as a scheduled container

Build and run the image with the AWS and notification variables available to the container:

docker build --platform linux/amd64 -t nyyu-monitor .
docker run --rm --env-file .env -p 3000:3000 nyyu-monitor

The default container runs the scheduler and serves the browser page together. Open http://localhost:3000; the page's Check button runs a check-only scan and does not send notifications or persist snapshots. Set PORT to use a different internal port, and publish the matching host port.

The container embeds config/monitor.json, starts a virtual X display, then runs the combined scheduler/web service as the non-root Playwright user. It does not run a check at startup: each source waits for its next configured cron occurrence. Croner prevents a second occurrence of the same source from overlapping an unfinished run. Different sources may run concurrently because their S3 keys are distinct.

Configuration is baked into the image, so changing a source or schedule requires rebuilding it. Run a single source manually by overriding the image entrypoint:

docker run --rm --env-file .env --entrypoint bun nyyu-monitor src/main.ts --source asrock-x670e-bios

Woodpecker validates pull requests, Renovate branches, tags, manual runs, and pushes to the default branch. On the default branch it publishes only ${DOCKER_REGISTRY}/${CI_REPO_OWNER}/monitor:latest through Kaniko, using the registry_username and registry_password secrets.