Allow jutsu reskins and link jutsu to parent
Pull Request
This allows jutsu to be reskinned and also link a jutsu to a parent. Updating a parent jutsu will update all children jutsu. When a jutsu is reskinned, it copies all data about the parent jutsu to the reskin copy including level and experience. The jutsu is automatically inserted into the list of learned jutsu. I set the training filter so it'll only show the "Reskin" type if the user has the jutsu already.
When a new jutsu is created, whether by staff or a player creating a reskin, it will display who created it. In the below screenshot it is a reskin, so "createdBy displays who reskinned it.
Limit on the number of reskins starts at 3(defined in constants), which can be increased by consuming a token (consumed count is in UserData). It checks the number of reskins the user has done and if its less than the allowed and the user has enough rep, the reskin succeeds. The screen will also display how many reskins are remaining. I just can't upload the pictures until vercel finishes the push.
All that's left is having the edit screen properly list all parent jutsu, not just a chunk of them. Speaking with content, we think it would be a good idea to have the report api used in the tavern also check to make sure that the descriptions being used are safe.
Current images of the reskin view. This may be adjusted as I continue.
License
By making this pull request, I confirm that I have the right to waive copyright and related rights to my contribution, and agree that all copyright and related rights in my contributions are waived, and I acknowledge that the Studie-Tech ApS organization has the copyright to use and modify my contribution for perpetuity.
The latest updates on your projects. Learn more about Vercel for GitHub.
Walkthrough
Adds first-class reskin support for bloodlines and jutsu across DB schema, server routers, validators, permissions, combat/runtime helpers, UI for create/edit/apply, item effects to increase reskin slots, and related frontend plumbing.
Changes
| Cohort / File(s) | Summary |
|---|---|
Constantsapp/drizzle/constants.ts |
Added ContentTypes "bloodline_reskin", "jutsu_reskin", RESKIN_LIMIT = 2, COST_RESKIN_JUTSU = 60, and IMG_MANUAL_JUTSU_RESKINS URL. |
Schema / DBapp/drizzle/schema.ts |
Added BloodlineReskin and JutsuReskin tables/types, indexes, relations; extended UserJutsu with reskinId and relations; added bloodlineReskinId to UserData. |
Server — Jutsu & Bloodline routersapp/src/server/api/routers/{jutsu.ts,bloodline.ts} |
New reskin endpoints (create/update/delete/get/getAll/getForX/getUser), helpers (fetchJutsuLoadouts, fetchBloodlineReskin, fetch helpers), adjustJutsuLevel → adjustUserJutsu (optional reskinId), AI moderation & action logging, reskin-aware queries. |
Server — Profile / Combat / Itemapp/src/server/api/routers/{profile.ts,combat.ts,item.ts} |
Persist and return bloodlineReskinId/activeReskin; apply reskins in combat via getReskinned* helpers; add item effect noncombatincreasereskins and persist extraReskinSlots. |
Validatorsapp/src/validators/{bloodline.ts,jutsu.ts,user.ts} |
Added base/create/update schemas for bloodline and jutsu reskins; added bloodlineReskinId to updateUserSchema. |
Permissions & Helpersapp/src/utils/permissions.ts, app/src/libs/{bloodline.ts,jutsu.ts,item.ts} |
Added canModerateReskin, canReskinFreely; getReskinnedBloodline, getReskinnedUserJutsu; allow noncombat reskin-slot items to be consumed. |
Combat types & actionsapp/src/libs/combat/{types.ts,actions.ts} |
Switched to WithRelations types for user jutsus/items, added IncreaseReskinSlots tag, injected reskin fields in action representations. |
Frontend — Player & Manual UIapp/src/app/{jutsus/page.tsx,manual/jutsu/**,manual/bloodline/**,profile/**} |
Jutsu page: reskin modals, cost/limit, mutations, UI hints; Manual pages: reskin listing, infinite scroll, edit pages, nav actions; profile/bloodline: popovers and reskin selects. |
Components & Layoutapp/src/layout/{CombatActions.tsx,ItemWithEffects.tsx,ContentFiltering.tsx,EditContent.tsx}, app/src/components/ui/textarea.tsx |
UI adjustments: Palette icon for reskinned items, createdBy display, icon-only filter/actions, controlled image field binding in EditContent, textarea controlled when value provided. |
Hooks & Miscapp/src/hooks/profile.ts, Makefile |
Added bloodline reskin select in profile hook; added force-push-staging Makefile target. |
Sequence Diagram(s)
sequenceDiagram
autonumber
actor U as User
participant C as Client (UI)
participant API as JutsuRouter/BloodlineRouter
participant DB as Database
participant AI as Moderation
participant L as ActionLog
U->>C: Open reskin create/update UI
C->>API: createReskin / updateReskin(input)
API->>DB: insert or load existing reskin
API->>AI: validateUserUpdateReason(reason, diff) (on update)
alt AI approves
API->>DB: update reskin
API->>L: log action
API-->>C: success
else AI rejects
API->>L: log rejection
API-->>C: error
end
sequenceDiagram
autonumber
participant GS as Game Server (combatRouter)
participant DB as DB (UserData, UserJutsu)
participant H as Helpers (getReskinned*)
GS->>DB: load users with bloodline (+activeReskin) and userJutsus (with activeReskin)
GS->>H: getReskinnedBloodline(bloodline, activeReskin?)
GS->>H: map getReskinnedUserJutsu over jutsus
GS->>Engine: start battle with transformed data
Engine-->>GS: results
Estimated code review effort
🎯 5 (Critical) | ⏱️ ~120 minutes
Possibly related PRs
- studie-tech/TheNinjaRPG#351 — overlaps jutsu router changes (fetchUserJutsus/selectJutsuLoadout signature and filtering).
- studie-tech/TheNinjaRPG#314 — touches combat tag/type definitions similar to
IncreaseReskinSlotsadditions. - studie-tech/TheNinjaRPG#552 — related to combat action/cooldown and injected action field changes.
Suggested labels
Needs Testing, Needs additional work, Jutsu Tag
Suggested reviewers
- theeneon
Pre-merge checks (2 passed, 1 warning)
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | ⚠️ Warning | Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
✅ Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title Check | ✅ Passed | The title succinctly summarizes the primary changes in the pull request, specifically enabling jutsu reskins and linking jutsus to their parents, providing clear context for reviewers without extraneous detail. |
| Description Check | ✅ Passed | The description effectively follows the repository template by outlining what was implemented, why the changes are necessary, including screenshots of the new UI, and concludes with the required license section, ensuring reviewers have all essential information. |
Poem
I hopped through code with palette bright,
Gave jutsu cloaks a fresh new light.
Bloodlines shimmer, two slots more —
I nibbled bugs and then I soar. 🐇🎨
✨ Finishing Touches
- [ ] 📝 Generate Docstrings
🧪 Generate unit tests
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
- [ ] Commit unit tests in branch
Phrosfire-patch-9
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-6 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-4 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.73 KB (-9 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-4 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-2 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-7 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-3 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-2 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-6 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-7 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-6 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-2 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-6 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-7 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-1 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-2 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-6 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-4 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-6 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-4 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-6 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-3 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
⚠️ Global Bundle Size Increased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (🟡 +1 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-7 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-5 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-7 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-6 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
📦 Next.js Bundle Analysis for tnr
This analysis was generated by the Next.js Bundle Analysis action. 🤖
🎉 Global Bundle Size Decreased
| Page | Size (compressed) |
|---|---|
global |
129.74 KB (-7 B) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!