Erstes Commit
This commit is contained in:
102
AGENTS.md
Normal file
102
AGENTS.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# Agent Instructions — `royalroadupdates`
|
||||
|
||||
## Project Purpose
|
||||
A small, self-contained Go CLI tool that checks RoyalRoad stories from a
|
||||
PocketBase bookmarks collection and reports their last-update times.
|
||||
|
||||
## Repository Layout
|
||||
|
||||
```
|
||||
.
|
||||
├── cmd/royalroadupdates/ Entry point and integration tests
|
||||
│ ├── main.go - CLI bootstrap, flag parsing (--json)
|
||||
│ └── e2e_test.go - End-to-end test: compiles binary, runs it,
|
||||
│ asserts JSON shape and entry count
|
||||
├── internal/
|
||||
│ ├── pocketbase/
|
||||
│ │ └── client.go - Authenticates and queries the
|
||||
│ │ /api/collections/bookmarks/records endpoint.
|
||||
│ │ Accepts filter, perPage, and field params.
|
||||
│ │ Returns a list of structs with URL fields.
|
||||
│ ├── royalroad/
|
||||
│ │ └── scraper.go - Given a URL, fetches the page, confirms it
|
||||
│ │ is a RoyalRoad fiction page, extracts the
|
||||
│ │ JSON-LD script block, parses name and
|
||||
│ │ dateModified into a struct.
|
||||
│ │ Returns zero-value + error for any failure
|
||||
│ │ so the caller can skip silently.
|
||||
│ ├── formatter/
|
||||
│ │ ├── table.go - Renders []Story as a plain-text aligned
|
||||
│ │ │ table with relative-time "Last Update"
|
||||
│ │ │ column.
|
||||
│ │ ├── json.go - Renders []Story as JSON (used with --json).
|
||||
│ │ └── relative.go - Computes "X minutes/hours/days/months/years
|
||||
│ │ ago" strings from time.Time.
|
||||
│ └── app.go - Orchestrates the full pipeline:
|
||||
│ 1. Load credentials (compile-time vars).
|
||||
│ 2. Query PocketBase for URLs.
|
||||
│ 3. Iterate URLs sequentially.
|
||||
│ 4. Collect valid RoyalRoad results.
|
||||
│ 5. Sort by dateModified descending.
|
||||
│ 6. Dispatch to appropriate formatter.
|
||||
├── .env - Real credentials (gitignored).
|
||||
├── .env.example - Template showing required env vars.
|
||||
├── .gitignore - Must include .env and the built binary.
|
||||
├── Makefile - All build, test, and check targets.
|
||||
├── go.mod - Standard Go module file.
|
||||
└── go.sum - Standard Go checksum file.
|
||||
```
|
||||
|
||||
## Code Style Rules
|
||||
|
||||
- **Formatting:** All Go source files must pass `gofmt`. The `make check` target
|
||||
will reject any diff.
|
||||
- **Imports:** Group standard library first, then third-party (none expected),
|
||||
then local/internal. `goimports` ordering is acceptable.
|
||||
- **Naming:** Exported identifiers use PascalCase; unexported use camelCase.
|
||||
Acronyms like HTTP, URL, JSON keep all-caps when exported (`FetchURL`,
|
||||
`ParseJSON`).
|
||||
- **Error handling:** Always check errors explicitly. Do not swallow errors
|
||||
silently unless the design calls for silent skipping (RoyalRoad per-item
|
||||
failures). Return errors wrapped with `fmt.Errorf("...: %w", err)` for
|
||||
context.
|
||||
- **Comments:** Every exported type and function has a concise GoDoc comment.
|
||||
Internal helpers may omit comments if their purpose is obvious from the name.
|
||||
- **No globals:** Avoid package-level mutable state. Pass dependencies (HTTP
|
||||
client, configuration) as struct fields or constructor parameters.
|
||||
- **HTTP client reuse:** Create one `http.Client` with a configured timeout and
|
||||
share it across requests. Do not use `http.DefaultClient` unwrapped.
|
||||
|
||||
## Build Rules
|
||||
|
||||
- **No local Go installation.** Use `make` targets which wrap
|
||||
`docker run --rm -v $(pwd):/src -w /src golang:1.22`.
|
||||
- **Credential injection:** The Makefile reads `.env` and passes values as
|
||||
`-ldflags '-X main.PB_URL=... -X main.PB_USER=... -X main.PB_PASSWORD=...'`.
|
||||
- **Output:** The compiled binary is written to `./royalroadupdates` in the
|
||||
repository root.
|
||||
- **Targets:**
|
||||
- `make build` — compile the binary.
|
||||
- `make check` — full quality loop (format, vet, test, e2e test).
|
||||
- `make clean` — remove the compiled binary.
|
||||
|
||||
## Testing Rules
|
||||
|
||||
- **Unit tests:** Cover pure helpers (e.g., `relative.go`, URL filtering logic)
|
||||
with table-driven tests. Use `t.Parallel()` where independent.
|
||||
- **End-to-end test (`e2e_test.go`):**
|
||||
- Uses the `.env` credentials and hits real services.
|
||||
- Compiles the binary via `os/exec` so it tests the actual build path.
|
||||
- Runs `./royalroadupdates --json`.
|
||||
- Assertions:
|
||||
1. Exit code 0.
|
||||
2. Stderr is empty.
|
||||
3. Stdout is valid JSON.
|
||||
4. JSON is a non-empty array.
|
||||
5. Array contains at least 3 entries.
|
||||
6. Each entry has a non-empty `name` and a parseable `date`.
|
||||
- Since this test hits live services, it is inherently non-deterministic in
|
||||
data content but deterministic in shape. Treat network/Cloudflare flakiness
|
||||
as a signal to tune delays rather than a code defect.
|
||||
- **Fix-and-rerun cycle:** If `make check` fails at any step, fix the root cause
|
||||
and rerun `make check` until all gates pass.
|
||||
Reference in New Issue
Block a user