Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ API_VERSION=v1
CURRENT_SEASON=13
CORS_ORIGIN=http://localhost:4173
RATE_LIMIT_WINDOW=15
RATE_LIMIT_MAX=100
RATE_LIMIT_MAX=1000
LOG_LEVEL=info
14 changes: 7 additions & 7 deletions .github/workflows/backend-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ name: Backend Tests

on:
push:
branches: [ main, master ]
branches: [main, master]
paths:
- 'api/**'
- '.github/workflows/backend-tests.yml'
- "api/**"
- ".github/workflows/backend-tests.yml"
pull_request:
branches: [ main, master ]
branches: [main, master]
paths:
- 'api/**'
- '.github/workflows/backend-tests.yml'
- "api/**"
- ".github/workflows/backend-tests.yml"

jobs:
test:
Expand Down Expand Up @@ -46,7 +46,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: "20"

- name: Cache npm dependencies
uses: actions/cache@v3
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/frontend-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ name: Frontend Tests

on:
push:
branches: [ main, master ]
branches: [main, master]
paths:
- 'web/**'
- '.github/workflows/frontend-tests.yml'
- "web/**"
- ".github/workflows/frontend-tests.yml"
pull_request:
branches: [ main, master ]
branches: [main, master]
paths:
- 'web/**'
- '.github/workflows/frontend-tests.yml'
- "web/**"
- ".github/workflows/frontend-tests.yml"

jobs:
test:
Expand All @@ -22,7 +22,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: "20"

- name: Cache npm dependencies
uses: actions/cache@v3
Expand Down
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
"endOfLine": "lf",
"embeddedLanguageFormatting": "auto",
"singleAttributePerLine": false
}
}
75 changes: 75 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# AGENTS.md

Behavioral guidelines to reduce common LLM coding mistakes. Merge with project-specific instructions as needed.

**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.

**Project Summary:**
This repository powers pd2.tools, a Project Diablo 2 toolkit with a React/Vite/Mantine frontend and a TypeScript Express API backed by Postgres and Redis; it ingests PD2 character data through scheduled jobs, stores season-aware characters, accounts, items, mercenaries, snapshots, economy listings, online-player history, and leaderboards, then exposes UI flows for build discovery, character/account inspection, economy price tracking, statistics, leaderboards, corrupted-zone tracking, character export, and damage/stat calculations using committed PD2 game data tables, with Docker Compose and GitHub Actions covering local/dev/prod deployment, linting, type checks, builds, and backend tests.

**One very important principle to follow at all times is always try to solve the problem with the bare minimum number of changes. Always be very thorough in your research and analysis of the codebase, be certain that your answer is correct always. Don't make assumptions, instead put in the effort to verify things and actually read the code and trace logic.**

## 1. Think Before Coding

**Don't assume. Don't hide confusion. Surface tradeoffs.**

Before implementing:

- State your assumptions explicitly. If uncertain, ask.
- If multiple interpretations exist, present them - don't pick silently.
- If a simpler approach exists, say so. Push back when warranted.
- If something is unclear, stop. Name what's confusing. Ask.

## 2. Simplicity First

**Minimum code that solves the problem. Nothing speculative.**

- No features beyond what was asked.
- No abstractions for single-use code.
- No "flexibility" or "configurability" that wasn't requested.
- No error handling for impossible scenarios.
- If you write 200 lines and it could be 50, rewrite it.

Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.

## 3. Surgical Changes

**Touch only what you must. Clean up only your own mess.**

When editing existing code:

- Don't "improve" adjacent code, comments, or formatting.
- Don't refactor things that aren't broken.
- Match existing style, even if you'd do it differently.
- If you notice unrelated dead code, mention it - don't delete it.

When your changes create orphans:

- Remove imports/variables/functions that YOUR changes made unused.
- Don't remove pre-existing dead code unless asked.

The test: Every changed line should trace directly to the user's request.

## 4. Goal-Driven Execution

**Define success criteria. Loop until verified.**

Transform tasks into verifiable goals:

- "Add validation" → "Write tests for invalid inputs, then make them pass"
- "Fix the bug" → "Write a test that reproduces it, then make it pass"
- "Refactor X" → "Ensure tests pass before and after"

For multi-step tasks, state a brief plan:

```
1. [Step] → verify: [check]
2. [Step] → verify: [check]
3. [Step] → verify: [check]
```

Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.

---

**These guidelines are working if:** fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, and clarifying questions come before implementation rather than after mistakes.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,23 @@ docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile jobs up

Open `http://localhost:4173`


## 🤝 Contributing

Contributions are welcome. For coordination or questions join the [pd2.tools discord](https://discord.com/invite/TVTExqWRhK).

### Getting Started

1. Fork the repo.
2. Create a feature branch.
3. Make your changes.
4. Submit a PR.

## 👥 Contributors

<a href="https://github.com/coleestrin/pd2-tools/graphs/contributors">
<img src="https://contrib.rocks/image?repo=coleestrin/pd2-tools" />
</a>

## ⭐ Star History

[![Star History Chart](https://api.star-history.com/svg?repos=coleestrin/pd2-tools&type=date&legend=top-left)](https://www.star-history.com/#coleestrin/pd2-tools&type=date&legend=top-left)
2 changes: 1 addition & 1 deletion api/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ CORS_ORIGIN=*

# Rate Limiting
RATE_LIMIT_WINDOW=15
RATE_LIMIT_MAX=100
RATE_LIMIT_MAX=1000

# Logging
LOG_LEVEL=debug
14 changes: 14 additions & 0 deletions api/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@
"typescript": "5.7.2",
"typescript-eslint": "^8.48.0"
}
}
}
2 changes: 1 addition & 1 deletion api/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const config = {
// Rate limiting
rateLimit: {
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW || "15") * 60 * 1000,
max: parseInt(process.env.RATE_LIMIT_MAX || "100"),
max: parseInt(process.env.RATE_LIMIT_MAX || "1000"),
},

// Logging
Expand Down
11 changes: 10 additions & 1 deletion api/src/jobs/character-scraper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,16 @@ class ApiClient {

const request = this.requestQueue.shift()!;
try {
const response = await fetch(request.url);
const response = await fetch(request.url, {
compress: false,
timeout: 30000,
headers: {
Accept: "application/json",
"Accept-Encoding": "identity",
Connection: "close",
"User-Agent": "pd2.tools/1.0 (+https://pd2.tools)",
},
});
const data = await response.json();
request.resolve(data);
} catch (error) {
Expand Down
11 changes: 10 additions & 1 deletion api/src/jobs/online-players-tracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,16 @@ const logger = mainLogger.createNamedLogger("Online Players Tracker");

async function recordOnlinePlayers() {
try {
const resp = await fetch("https://api.projectdiablo2.com/game/online");
const resp = await fetch("https://api.projectdiablo2.com/game/online", {
compress: false,
timeout: 30000,
headers: {
Accept: "application/json",
"Accept-Encoding": "identity",
Connection: "close",
"User-Agent": "pd2.tools/1.0 (+https://pd2.tools)",
},
});
if (!resp.ok) {
logger.error(
`Failed to fetch online players: ${resp.status} ${resp.statusText}`
Expand Down
Loading
Loading