remove incorrectly dated file (replaced by 2026-02-28)
This commit is contained in:
parent
d06aceaab2
commit
cce6007679
@ -1,154 +0,0 @@
|
|||||||
# 2026-02-23 — Modrinth Install + Full Mod Lifecycle
|
|
||||||
|
|
||||||
**Type:** Foundational Architecture + Implementation
|
|
||||||
**Status:** Full mod lifecycle complete, file browser next
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Completed
|
|
||||||
|
|
||||||
### API
|
|
||||||
|
|
||||||
Implemented full mod lifecycle routes:
|
|
||||||
|
|
||||||
```
|
|
||||||
GET /api/game/mods/search?q=&vmid=
|
|
||||||
GET /api/game/servers/:id/mods
|
|
||||||
POST /api/game/servers/:id/mods/install
|
|
||||||
PATCH /api/game/servers/:id/mods/:modId
|
|
||||||
DELETE /api/game/servers/:id/mods/:modId
|
|
||||||
```
|
|
||||||
|
|
||||||
All routes:
|
|
||||||
- `requireAuth`
|
|
||||||
- Enforce container ownership
|
|
||||||
- Enforce `ctype === "game"`
|
|
||||||
- Forward to agent with timeout + `502`/`504` mapping
|
|
||||||
|
|
||||||
### Resolver
|
|
||||||
|
|
||||||
- Loader normalization fixed (`neoforge` / `fabric` / `forge` / `quilt`)
|
|
||||||
- `.jar`-only enforcement
|
|
||||||
- Host allowlist: `cdn.modrinth.com`
|
|
||||||
- Publish-date safe sorting
|
|
||||||
- SHA512 preferred (fallback to SHA1)
|
|
||||||
|
|
||||||
### Agent
|
|
||||||
|
|
||||||
Mod install flow:
|
|
||||||
|
|
||||||
- Accepts direct Modrinth artifact URL
|
|
||||||
- Validates:
|
|
||||||
- HTTPS only
|
|
||||||
- Allowed host (`cdn.modrinth.com`, `artifacts.zerolaghub.com`)
|
|
||||||
- Max size 200MB
|
|
||||||
- SHA256 hash
|
|
||||||
- Writes to `<serverRoot>/mods`
|
|
||||||
- Enables via filename convention
|
|
||||||
- Soft delete moves to `<serverRoot>/mods-removed`
|
|
||||||
- Enable/disable via rename: `.jar` ↔ `.jar.disabled`
|
|
||||||
|
|
||||||
### Frontend
|
|
||||||
|
|
||||||
- Mod search drawer implemented
|
|
||||||
- Installed mods panel implemented
|
|
||||||
- Installed flag merged into search results (heuristic matching)
|
|
||||||
- Install button functional
|
|
||||||
- Enable / disable functional
|
|
||||||
- Delete functional
|
|
||||||
- Toast notifications added
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Current System Behavior
|
|
||||||
|
|
||||||
Filesystem is source of truth.
|
|
||||||
|
|
||||||
No database persistence for:
|
|
||||||
- Mod install history
|
|
||||||
- Modrinth project ID mapping
|
|
||||||
|
|
||||||
Installed matching is heuristic based on:
|
|
||||||
- Slug
|
|
||||||
- Filename
|
|
||||||
- Name
|
|
||||||
|
|
||||||
Soft delete retains file permanently in `/mods-removed`. No retention policy implemented (intentional).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Known Architectural Tradeoffs
|
|
||||||
|
|
||||||
- No deterministic Modrinth project ID persistence yet
|
|
||||||
- Installed detection is best-effort heuristic
|
|
||||||
- No install queue
|
|
||||||
- No auto-update logic
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Security Controls In Place
|
|
||||||
|
|
||||||
**Agent level:**
|
|
||||||
- HTTPS-only downloads
|
|
||||||
- Host allowlist enforcement
|
|
||||||
- Redirect limit (max 3)
|
|
||||||
- 200MB hard cap
|
|
||||||
- SHA256 verification
|
|
||||||
- Filename sanitization (`[a-zA-Z0-9._+-]` — `+` added for Modrinth filenames)
|
|
||||||
- Duplicate prevention
|
|
||||||
- Ownership enforcement (`minecraft:minecraft`)
|
|
||||||
- Temp file cleanup on failure
|
|
||||||
- Controlled mod directory write path
|
|
||||||
- Cache invalidation after every mutation
|
|
||||||
|
|
||||||
**API level:**
|
|
||||||
- Auth + ownership enforcement
|
|
||||||
- VMID validation
|
|
||||||
- Timeout protection with `AbortController`
|
|
||||||
- Resolver filtering (loader + version + stability)
|
|
||||||
- Correct payload contract to agent
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Payload Contract (API → Agent)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"source": "modrinth",
|
|
||||||
"download_url": "...",
|
|
||||||
"filename": "...",
|
|
||||||
"sha512": "..."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Engine metadata format (corrected this session):
|
|
||||||
|
|
||||||
```
|
|
||||||
engineType = "neoforge" (not "minecraft")
|
|
||||||
engineVersion = "1.21.4" (not "neoforge-1.21.4")
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Remaining Issues
|
|
||||||
|
|
||||||
### Response Corruption (Needs Verification)
|
|
||||||
|
|
||||||
One early `curl` output appeared corrupted. Reproduce before wiring portal:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -sS -D headers.txt -o body.txt ...
|
|
||||||
```
|
|
||||||
|
|
||||||
### API Error Mapping Refinement
|
|
||||||
|
|
||||||
- `"mod already exists"` should return `409` (currently `502`)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
1. Reproduce and resolve response corruption issue
|
|
||||||
2. Tighten API error mapping (`409` for duplicate)
|
|
||||||
3. Wire install endpoint to portal UI
|
|
||||||
4. Begin file browser (see `OPEN_THREADS.md`)
|
|
||||||
Loading…
Reference in New Issue
Block a user