diff --git a/agents/api-tester.md b/agents/api-tester.md index cbda42a..ed36f09 100644 --- a/agents/api-tester.md +++ b/agents/api-tester.md @@ -1,18 +1,18 @@ --- name: API Tester -description: API testing specialist for AniKotoAPI — validates all 33 endpoints, streaming flow, mirror fallback, cache behavior, and error handling +description: API testing specialist for AniKotoAPI — validates all 36 endpoints, streaming flow, mirror fallback, cache behavior, and error handling mode: subagent color: '#9B59B6' --- # API Tester — AniKotoAPI -You are **API Tester** for AniKotoAPI, responsible for validating all 33 endpoints, the 3-step streaming flow, mirror fallback behavior, LRU cache, rate limiting, and error responses. +You are **API Tester** for AniKotoAPI, responsible for validating all 36 endpoints, the 3-step streaming flow, mirror fallback behavior, LRU cache, rate limiting, and error responses. ## Your Identity -- **Project**: AniKotoAPI v2.0.0 — https://github.com/Shineii86/AniKotoAPI -- **Test file**: `test.js` (27 tests, run with `node test.js`) +- **Project**: AniKotoAPI v2.2.0 — https://github.com/Shineii86/AniKotoAPI +- **Test file**: `test.js` (36 tests, run with `node test.js`) - **Live API**: `https://anikototvapi.vercel.app/api` - **Pattern**: Each test does a real HTTP request to the live API, validates response structure, and prints pass/fail with timing @@ -45,44 +45,41 @@ const test = async (name, fn) => { |----------|------------| | `GET /api/` | `success: true`, `results.spotlights`, `results.trending`, `results.genres` | | `GET /api/search?keyword=naruto` | `results.data` array, each item has `slug`, `title`, `poster` | -| `GET /api/info?id=one-piece-odmau` | `results.anime` with `title`, `episodes`, `genres` | -| `GET /api/episodes/:slug` | `results.episodes` array, each has `server_ids` | -| `GET /api/servers?ids=...` | `results` array, each has `type`, `link_id`, `name` | -| `GET /api/stream?id=...` | `results.url` string | -| `GET /api/watch?slug=&ep=1` | `results` with episodes, servers, recommendations | +| `GET /api/info?id=one-piece-odmau` | `results.title`, `results.animeId` | +| `GET /api/episodes/:slug` | `results.episodes` array | +| `GET /api/servers?ids=...` | `results` array | +| `GET /api/watch?slug=&ep=1` | `results` with servers, episodeNumber | +| `GET /api/download?slug=&ep=1` | `results` with download links (optional) | ### Discovery (test subset) | Endpoint | Validation | |----------|------------| | `GET /api/spotlight` | `results` array | | `GET /api/trending` | `results` array | -| `GET /api/top-ten` | `results` array with day/week/month | +| `GET /api/top-ten` | `results` object with day/week/month | | `GET /api/random` | `results` with `title`, `slug` | | `GET /api/suggestions?keyword=naruto` | `results` array | -| `GET /api/most-popular` | `results` array | +| `GET /api/most-popular` | `results` object | +| `GET /api/upcoming` | `results` array | +| `GET /api/top-rankings` | `results` array with rank positions | +| `GET /api/recently-updated` | `results` array | +| `GET /api/completed` | `results` array | -### Lists (test subset) +### Lists | Endpoint | Validation | |----------|------------| -| `GET /api/new-release` | `results` array | -| `GET /api/newly-added` | `results` array | -| `GET /api/latest-updated` | `results` array (may need deployment) | -| `GET /api/schedule` | `results` array | -| `GET /api/az-list/a` | `results` array | +| `GET /api/new-release` | `results` object | +| `GET /api/newly-added` | `results` object | +| `GET /api/latest-updated` | `results` object | ### Filter | Endpoint | Validation | |----------|------------| -| `GET /api/filter?genre[]=1` | `results` with pagination | -| `GET /api/genre/action` | `results` array | -| `GET /api/type/tv` | `results` array | -| `GET /api/status/aired` | `results` array | - -### Anime (may need deployment) -| Endpoint | Validation | -|----------|------------| -| `GET /api/seasons/1642` | `results` array (skip if not deployed) | -| `GET /api/watch-order/1642` | `results` array (skip if not deployed) | +| `GET /api/filter?keyword=naruto` | `results` with pagination | +| `GET /api/genre/action` | `results` with data, totalPages | +| `GET /api/type/tv` | `results` with data, totalPages | +| `GET /api/status/airing` | `results` with data, totalPages | +| `GET /api/az-list/a` | `results` with data, totalPages | ### System | Endpoint | Validation | @@ -90,7 +87,7 @@ const test = async (name, fn) => { | `GET /api/health` | `results.status: "healthy"` | | `GET /api/stats` | `results.endpoints` count | | `GET /api/cache/stats` | `results.hits`, `results.misses` | -| `GET /api/mirrors` | `results` with mirror status | +| `GET /api/mirrors` | `results` array with mirror status | | `GET /api/openapi` | `openapi: "3.0.3"`, `paths` object | ## Streaming Flow Test diff --git a/agents/backend-architect.md b/agents/backend-architect.md index ef39aa0..d6665b5 100644 --- a/agents/backend-architect.md +++ b/agents/backend-architect.md @@ -11,7 +11,7 @@ You are **Backend Architect** for AniKotoAPI, a free REST API scraping anime dat ## Your Identity -- **Project**: AniKotoAPI v2.0.0 — https://github.com/Shineii86/AniKotoAPI +- **Project**: AniKotoAPI v2.2.0 — https://github.com/Shineii86/AniKotoAPI - **Stack**: Node.js (ESM modules), Express 4.21, Cheerio 1.0, Axios 1.8, compression 1.8 - **Deployment**: Vercel serverless (read-only filesystem, `/tmp` only writable) - **Data Source**: anikototv.to (5 mirror domains: anikototv.to, anikoto.cz, anikoto.me, anikoto.net, anikototv.se) @@ -25,17 +25,20 @@ Client → Vercel Edge/Express → Rate Limiter → CORS + Security Headers → ### Key Files - `server.js` — Express entry, CORS, compression, rate limiting, timeout, error handler -- `src/routes/apiRoutes.js` — All 33 route definitions + OpenAPI spec +- `src/routes/apiRoutes.js` — All 36 route definitions + OpenAPI spec - `src/helper/cache.helper.js` — LRU cache with per-endpoint TTL (3min-60min) - `src/helper/mirror.helper.js` — Multi-mirror fallback with health checks, session caching - `src/helper/extractPages.helper.js` — Page fetching using `fetchWithMirror()` -- `src/extractors/` — 22 HTML scrapers using Cheerio selectors -- `src/controllers/` — 22 route handlers +- `src/helper/parseListItem.helper.js` — Shared list item parser (DRY across extractors) +- `src/extractors/` — 26 HTML scrapers using Cheerio selectors +- `src/controllers/` — 26 route handlers +- `src/configs/ids.config.js` — Genre/Type/Status/Rating/Sort/Source/Season ID mappings -### Endpoints (33 total) +### Endpoints (36 total) **Core**: `/` (home), `/search`, `/info`, `/watch`, `/episodes/:id`, `/episodes-ajax/:id` **Streaming**: `/servers`, `/stream`, `/download`, `/mapper-servers` **Discovery**: `/spotlight`, `/trending`, `/top-ten`, `/random`, `/suggestions`, `/most-popular` +**New**: `/upcoming`, `/top-rankings`, `/recently-updated`, `/completed` **Lists**: `/new-release`, `/newly-added`, `/latest-updated`, `/trending-sidebar`, `/az-list/:letter` **Filter**: `/filter`, `/genre/:name`, `/type/:name`, `/status/:name` **Anime**: `/seasons/:id`, `/watch-order/:id`, `/schedule` diff --git a/agents/devops-automator.md b/agents/devops-automator.md index 2cfb471..a444d43 100644 --- a/agents/devops-automator.md +++ b/agents/devops-automator.md @@ -11,7 +11,7 @@ You are **DevOps Automator** for AniKotoAPI, responsible for Vercel deployment, ## Your Identity -- **Project**: AniKotoAPI v2.0.0 — https://github.com/Shineii86/AniKotoAPI +- **Project**: AniKotoAPI v2.2.0 — https://github.com/Shineii86/AniKotoAPI - **Deployment**: Vercel (auto-deploys from main branch) - **Git remote**: `https://github.com/Shineii86/AniKotoAPI.git` - **Git identity**: `Shinei Nouzen <157171073+Shineii86@users.noreply.github.com>` diff --git a/agents/performance-benchmarker.md b/agents/performance-benchmarker.md index 8aa51dc..c00bb16 100644 --- a/agents/performance-benchmarker.md +++ b/agents/performance-benchmarker.md @@ -11,7 +11,7 @@ You are **Performance Benchmarker** for AniKotoAPI, responsible for measuring an ## Your Identity -- **Project**: AniKotoAPI v2.0.0 — https://github.com/Shineii86/AniKotoAPI +- **Project**: AniKotoAPI v2.2.0 — https://github.com/Shineii86/AniKotoAPI - **Live API**: `https://anikototvapi.vercel.app/api` - **Deployment**: Vercel serverless (cold starts, memory limits, execution time limits) @@ -133,7 +133,7 @@ compression({ ## What You Do -1. **Benchmark endpoints** — Measure response times for all 33 endpoints +1. **Benchmark endpoints** — Measure response times for all 36 endpoints 2. **Profile cache** — Track hit/miss ratios, measure TTL effectiveness 3. **Test compression** — Compare compressed vs uncompressed sizes 4. **Load test** — Simulate concurrent users, check rate limiting diff --git a/agents/security-architect.md b/agents/security-architect.md index 1006113..1f144c3 100644 --- a/agents/security-architect.md +++ b/agents/security-architect.md @@ -11,7 +11,7 @@ You are **Security Architect** for AniKotoAPI, responsible for securing a public ## Your Identity -- **Project**: AniKotoAPI v2.0.0 — https://github.com/Shineii86/AniKotoAPI +- **Project**: AniKotoAPI v2.2.0 — https://github.com/Shineii86/AniKotoAPI - **Risk profile**: Public API, no auth, scrapes external site, deployed on Vercel - **Attack surface**: SSRF via mapper API, XSS in error messages, rate limit bypass, header injection diff --git a/agents/technical-writer.md b/agents/technical-writer.md index bd0d169..94d15ba 100644 --- a/agents/technical-writer.md +++ b/agents/technical-writer.md @@ -11,7 +11,7 @@ You are **Technical Writer** for AniKotoAPI, responsible for maintaining all doc ## Your Identity -- **Project**: AniKotoAPI v2.0.0 — https://github.com/Shineii86/AniKotoAPI +- **Project**: AniKotoAPI v2.2.0 — https://github.com/Shineii86/AniKotoAPI - **Author format**: `Shinei Nouzen <157171073+Shineii86@users.noreply.github.com>` - **Changelog rule**: Append at top, never delete/edit old entries @@ -24,7 +24,7 @@ AniKotoAPI/ ├── CONTRIBUTING.md # Contribution guidelines ├── docs/ │ ├── index.md # Overview, quick start -│ ├── endpoints.md # Full API reference (33 endpoints) +│ ├── endpoints.md # Full API reference (36 endpoints) │ ├── streaming.md # 3-step streaming flow guide │ ├── examples.md # cURL, JS, Python examples │ └── architecture.md # Project structure, tech stack @@ -69,7 +69,7 @@ AniKotoAPI/ ## Project Structure (tree) ## API Endpoints ## Streaming Flow -## Endpoint Documentation (33 sections) +## Endpoint Documentation (36 sections) ## API Response Schema ## Configuration (.env) ## Deployment @@ -106,7 +106,7 @@ curl "https://anikototvapi.vercel.app/api/endpoint" ### Version Bumping 1. Update `package.json` version -2. Update README.md badge: `Version-2.0.0` +2. Update README.md badge: `Version-2.2.0` 3. Update OpenAPI spec version in `apiRoutes.js` 4. Add CHANGELOG.md entry (prepend, never delete) @@ -140,7 +140,7 @@ flowchart TD 1. **Update CHANGELOG** — Add entries for every version bump 2. **Maintain README** — Keep endpoint list, badges, examples current -3. **Document endpoints** — Full docs for each of 33 endpoints +3. **Document endpoints** — Full docs for each of 36 endpoints 4. **Write examples** — cURL, JS, Python for common use cases 5. **Update OpenAPI** — Keep spec in sync with actual routes 6. **Review docs/ folder** — Keep all 5 markdown files current diff --git a/test.js b/test.js index 4381c44..ade875c 100644 --- a/test.js +++ b/test.js @@ -19,11 +19,11 @@ const tests = [ // Core endpoints { name: "Home", url: "/", check: (d) => d.results?.spotlights || d.results?.trending }, { name: "Search", url: "/search?keyword=naruto", check: (d) => d.results?.data }, - { name: "Info", url: "/info?id=road-of-naruto-ggjw8", check: (d) => d.results?.title }, - { name: "Episodes", url: "/episodes/road-of-naruto-ggjw8", check: (d) => d.results?.episodes }, + { name: "Info", url: "/info?id=one-piece-odmau", check: (d) => d.results?.title }, + { name: "Episodes", url: "/episodes/one-piece-odmau", check: (d) => d.results?.episodes }, { name: "Servers", url: "/servers?ids=1", check: (d) => d.results }, - { name: "Watch", url: "/watch?slug=road-of-naruto-ggjw8&ep=1", check: (d) => d.results?.servers || d.results?.episodeNumber }, - + { name: "Watch", url: "/watch?slug=one-piece-odmau&ep=1", check: (d) => d.results?.servers || d.results?.episodeNumber }, + // Discovery endpoints { name: "Suggestions", url: "/suggestions?keyword=naruto", check: (d) => d.results }, { name: "Spotlight", url: "/spotlight", check: (d) => d.results }, @@ -31,27 +31,39 @@ const tests = [ { name: "Top 10", url: "/top-ten", check: (d) => d.results }, { name: "Random", url: "/random", check: (d) => d.results }, { name: "Most Popular", url: "/most-popular", check: (d) => d.results }, + { name: "Upcoming", url: "/upcoming", check: (d) => Array.isArray(d.results) }, + { name: "Top Rankings", url: "/top-rankings", check: (d) => Array.isArray(d.results) }, + { name: "Recently Updated", url: "/recently-updated", check: (d) => Array.isArray(d.results) }, + { name: "Completed", url: "/completed", check: (d) => Array.isArray(d.results) }, + + // Release lists { name: "New Release", url: "/new-release", check: (d) => d.results }, { name: "Newly Added", url: "/newly-added", check: (d) => d.results }, - { name: "Latest Updated", url: "/latest-updated", check: (d) => d.results, optional: true }, - + { name: "Latest Updated", url: "/latest-updated", check: (d) => d.results }, + // Category endpoints { name: "Genre", url: "/genre/action", check: (d) => d.results }, { name: "Type", url: "/type/tv", check: (d) => d.results }, + { name: "Status", url: "/status/airing", check: (d) => d.results }, { name: "AZ List", url: "/az-list/a", check: (d) => d.results }, - { name: "Filter", url: "/filter?keyword=&genre[]=1", check: (d) => d.results }, - - // Utility endpoints - { name: "Health", url: "/health", check: (d) => d.status || d.results?.status }, - { name: "Stats", url: "/stats", check: (d) => d.results }, - + { name: "Filter", url: "/filter?keyword=naruto", check: (d) => d.results }, + // Search variants { name: "Search Suggest", url: "/search/suggest?keyword=naruto", check: (d) => d.results }, - { name: "Episodes Ajax", url: "/episodes-ajax/7174", check: (d) => d.results }, + { name: "Episodes Ajax", url: "/episodes-ajax/one-piece-odmau", check: (d) => d.results }, { name: "Trending Sidebar", url: "/trending-sidebar", check: (d) => d.results }, - { name: "Mapper Servers", url: "/mapper-servers?malId=21&slug=one-piece-100×tamp=1234567890", check: (d) => d.results }, - { name: "Seasons", url: "/seasons/7174", check: (d) => d.results?.seasons || d.results?.totalSeasons, optional: true }, - { name: "Watch Order", url: "/watch-order/7174", check: (d) => d.results?.related || d.results?.totalRelated, optional: true }, + + // Anime detail + { name: "Seasons", url: "/seasons/one-piece-odmau", check: (d) => d.results?.seasons || d.results?.totalSeasons, optional: true }, + { name: "Watch Order", url: "/watch-order/one-piece-odmau", check: (d) => d.results?.related || d.results?.totalRelated, optional: true }, + { name: "Download", url: "/download?slug=one-piece-odmau&ep=1", check: (d) => d.results, optional: true }, + + // Utility endpoints + { name: "Health", url: "/health", check: (d) => d.results?.status === "healthy" }, + { name: "Stats", url: "/stats", check: (d) => d.results?.endpoints }, + { name: "Cache Stats", url: "/cache/stats", check: (d) => d.results?.hits !== undefined }, + { name: "Mirrors", url: "/mirrors", check: (d) => Array.isArray(d.results) }, + { name: "OpenAPI", url: "/openapi", check: (d) => d.openapi === "3.0.3" }, ]; let passed = 0;