feat(DRW-001) initial fixes
CI/CD / Build (push) Successful in 1m3s
CI/CD / Frontend Build (push) Successful in 21s
CI/CD / Unit Tests (push) Failing after 1m39s
CI/CD / Docker (push) Skipped
CI/CD / Frontend Docker (push) Successful in 2m24s

This commit is contained in:
2026-09-13 20:55:01 +03:00
parent edb4cd8613
commit 4bdacf3e3c
3 changed files with 48 additions and 26 deletions
+21
View File
@@ -4,6 +4,7 @@ on:
push:
branches:
- '**'
workflow_dispatch:
env:
REGISTRY: gitea.kawaii-alyssa.dev
@@ -41,6 +42,24 @@ jobs:
name: Unit Tests
needs: build
runs-on: ubuntu-latest
# cargo build never touches a database (no compile-time-checked sqlx
# macros are used anywhere), but the tests do -- #[sqlx::test] spins up
# a real, freshly-migrated database per test, which needs an actual
# Postgres server to connect to and CREATE DATABASE against.
services:
postgres:
image: postgres:15-alpine
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -61,6 +80,8 @@ jobs:
restore-keys: rust-${{ runner.os }}-
- name: Run tests
env:
DATABASE_URL: postgres://test:test@localhost:5432/test
run: cargo test --release --locked
docker:
+1
View File
@@ -1,3 +1,4 @@
/target
/.claude
/.idea
.env
+26 -26
View File
@@ -1,35 +1,35 @@
# 🎲 Dota Random
# 🎲 Dota Random 🌸
> "I-it's not like I made a whole randomizer just so YOU could have chaotic fun in your games or anything... b-baka."
> "I-it's not like I made a whole randomizer just so YOU could have chaotic fun in your games or anything... b-baka." 💢
Fine, FINE. Since you're making me explain it: this is a Dota 2 hero + item build randomizer. You pick how much chaos you want — scope it to melee heroes, lock item tags, disable half the randomness if you're a coward — and it rolls you a hero, a full item build (slot 1 is *always* boots, don't argue with me about it), neutral item candidates per stage, enchantments, and tells you when you're allowed to buy your Aghanim's. Not that I care if you actually use it properly.
Fine, FINE. Since you're making me explain it: this is a Dota 2 hero + item build randomizer. You pick how much chaos you want — scope it to melee heroes, lock item tags, disable half the randomness if you're a coward — and it rolls you a hero, a full item build (slot 1 is *always* boots, don't argue with me about it), neutral item candidates per stage, enchantments, and tells you when you're allowed to buy your Aghanim's. Not that I care if you actually use it properly. 🎀
It's not a toy. ...Okay it's kind of a toy. Shut up.
It's not a toy. ...Okay it's kind of a toy. Shut up. ✨
## What it actually does
## 🌷 What it actually does
- **Hero scope** — filter by attack type and/or primary attribute, or leave it wide open if you're feeling brave
- **Item scope** — restrict rolls to items carrying specific purpose tags (Physical Damage, Disable, Sustain, etc.)
- **Slot 1 is always boots** — every existing boots item in the game is eligible, including separate grades like Boots of Travel / Boots of Travel 2 and Dagon's five levels, each rolled as its own distinct outcome
- **Slot 1 is always boots** 👢 — every existing boots item in the game is eligible, including separate grades like Boots of Travel / Boots of Travel 2 and Dagon's five levels, each rolled as its own distinct outcome
- **Neutral items, honestly modeled** — each active tier suggests 2 real candidates, because the app can't actually control what drops in your match. You click whichever one you got, or browse the full tier if neither matches
- **Enchantments, guaranteed** — no RNG-within-RNG nonsense here. If enchantment rolling is on, you get one, scoped correctly to your hero's primary attribute (including the "works on literally any hero" ones — yes, those exist, no I didn't forget about them)
- **Enchantments, guaranteed** ⭐ — no RNG-within-RNG nonsense here. If enchantment rolling is on, you get one, scoped correctly to your hero's primary attribute (including the "works on literally any hero" ones — yes, those exist, no I didn't forget about them)
- **Aghanim's Scepter & Shard roll as normal items now** — no special-cased fake probability. You also get to say whether you're "allowed" to buy them mid-build or only after your 6 slots are full, for whenever they don't get rolled naturally
- **Reroll anything** — hero, a single item slot, a specific neutral tier, a specific enchantment tier. Rerolling your hero also refreshes your neutral items and enchantments, since a new hero deserves a fresh itemization pass, o-obviously
- **Reroll anything** 🔁 — hero, a single item slot, a specific neutral tier, a specific enchantment tier. Rerolling your hero also refreshes your neutral items and enchantments, since a new hero deserves a fresh itemization pass, o-obviously
- **Manual override, always available** — disable randomness for any slot/dimension and pick it yourself instead
## Stack
## 💐 Stack
Not that you need to know this to use it, but since you're being nosy:
| Layer | Tech |
|---|---|
| Backend | Rust, [axum](https://github.com/tokio-rs/axum), [sqlx](https://github.com/launchbadge/sqlx) (Postgres) |
| Frontend | React, TypeScript, Vite, Tailwind CSS |
| Database | PostgreSQL |
| Layer | Tech |
|-------------|--------------------------------------------------------------------------------------------------------------------------------------|
| Backend | Rust, [axum](https://github.com/tokio-rs/axum), [sqlx](https://github.com/launchbadge/sqlx) (Postgres) |
| Frontend | React, TypeScript, Vite, Tailwind CSS |
| Database | PostgreSQL |
| Data source | Scraped live from [Liquipedia](https://liquipedia.net/dota2/) via Python scripts (no hardcoded/stale game data, thank you very much) |
| Deployment | Docker Compose + a Gitea Actions CI/CD pipeline |
| Deployment | Docker Compose + a Gitea Actions CI/CD pipeline |
## Getting it running (pay attention, I'm not repeating myself)
## 🌼 Getting it running (pay attention, I'm not repeating myself)
### 1. Database
@@ -53,7 +53,7 @@ python scripts/scrape_items.py
sqlx migrate run
```
Yes, this means the roster stays current with whatever patch Liquipedia reflects. Rerun the scripts whenever you want fresh data. I'm not doing that part for you.
Yes, this means the roster stays current with whatever patch Liquipedia reflects. Rerun the scripts whenever you want fresh data. I'm not doing that part for you. 🌱
### 2. Backend
@@ -71,7 +71,7 @@ npm install
npm run dev
```
Runs on `:5173` with a dev proxy to the backend, so it just works. You're welcome.
Runs on `:5173` with a dev proxy to the backend, so it just works. You're welcome. 💗
### 4. Or just use Docker Compose
@@ -79,9 +79,9 @@ Runs on `:5173` with a dev proxy to the backend, so it just works. You're welcom
docker compose up
```
...if the images are actually built and pushed, which they will be, because there's a whole CI pipeline for it. I didn't half-ass this.
...if the images are actually built and pushed, which they will be, because there's a whole CI pipeline for it. I didn't half-ass this. ✨
## Project layout, since you'll get lost otherwise
## 🎀 Project layout, since you'll get lost otherwise
```
src/ Rust backend (axum handlers, roll logic, models)
@@ -91,16 +91,16 @@ frontend/ React + TypeScript SPA
.gitea/ CI/CD workflow
```
## A note on the data
## 🌸 A note on the data
Heroes, items, and enchantments are scraped from Liquipedia's Dota 2 wiki, not hand-typed or pulled from memory — patches change too fast for that to stay accurate, and I refuse to ship stale data. The scrapers check each item's actual current status (active / removed / unreleased / hidden) rather than trusting whatever list happens to mention it, because apparently even wikis get this wrong sometimes.
Heroes, items, and enchantments are scraped from Liquipedia's Dota 2 wiki, not hand-typed or pulled from memory — patches change too fast for that to stay accurate, and I refuse to ship stale data. The scrapers check each item's actual current status (active / removed / unreleased / hidden) rather than trusting whatever list happens to mention it, because apparently even wikis get this wrong sometimes. 🧐
## Disclaimer
## 📎 Disclaimer
Part of this project — the whole frontend, a chunk of the Rust backend, the data scrapers, the CI/CD setup — was written with AI assistance. It's not like every line was hand-crafted by a lone genius at 3am. Mostly. I just don't like writing boilerplate code or code I already know how to write! Baka!
Part of this project — the whole frontend, a chunk of the Rust backend, the data scrapers, the CI/CD setup — was written with AI assistance. It's not like every line was hand-crafted by a lone genius at 3am. Mostly. I just don't like writing boilerplate code or code I already know how to write! Baka! 💢
## Author
## 🌷 Author
**ItzYumeii**
...I guess if you actually enjoy using this, that's... fine. Not that it matters to me or anything.
...I guess if you actually enjoy using this, that's... fine. Not that it matters to me or anything. 🩷