Commit 7611d42
Add entity system + unified polymorphic reward type (#19)
* Add entity module — RPG entity system with admin dashboard (#19)
Phase 1 of the entity system: Schema/Blueprint/Skin/FormationConfig
CRUD with full admin dashboard and i18n support.
Backend (apps/server):
- 8 new tables: entity_schemas, entity_blueprints, entity_blueprint_skins,
entity_instances, entity_slot_assignments, entity_formation_configs,
entity_formations, entity_action_logs
- Flexible schema system: orgs define entity types (hero, weapon, skill)
with configurable stats, tags, slots, level/rank/synthesis rules
- Tag-based slot compatibility (e.g. warrior heroes only accept warrior weapons)
- Service layer with full CRUD + alias conflict detection + cascade deletion
- 20 admin REST endpoints with OpenAPI/Zod validation
- 32 service tests (all passing against real Neon DB)
- Migration 0014 generated and applied
Frontend (apps/admin):
- Entity dashboard with tabbed view (schemas + formation configs)
- Schema create/detail pages with dynamic stat/tag/slot editors
- Blueprint create/detail pages with schema-driven forms
- Skin create page
- Formation config create page
- 6 reusable components (SchemaTable, SchemaForm, BlueprintTable,
BlueprintForm, SkinTable, FormationConfigTable)
- React Query hooks for all CRUD operations
- Full i18n (en + zh) with ~75 new message keys
- Sidebar navigation entry with Sparkles icon
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add entity instance management, progression, slots, and formations
Phase 2-5 of the entity system — all runtime operations:
Instance management:
- acquireEntity: create new instances with computed initial stats
- listInstances: filter by schemaId/blueprintId (backpack categories)
- getInstance: returns instance + equipped slot details
- discardEntity: with lock protection and equipped-check
- toggleLock: prevent accidental discard/synthesis
Progression system:
- addExp: direct experience injection (battle rewards)
- levelUp: consumes item materials per blueprint.levelUpCosts config
- rankUp: consumes materials, advances rank (N→R→SR→SSR)
- synthesize: merge N duplicate entities, consuming feeds + materials
Stat computation pipeline:
- Pure function: base + growth×(level-1) + rank bonuses + equipment + skin
- Cached in computedStats JSONB, recomputed on every mutation
- Read paths return cached values (zero computation)
Slot system:
- equip/unequip with schema + tag compatibility validation
- $owner.class dynamic tag matching (warrior heroes accept warrior weapons)
- Unique constraint: one entity can only be in one slot at a time
Formations:
- updateFormation: upsert with schema/duplicate validation
- listFormations: per-config, per-user
Client API: 14 new endpoints under /api/client/entity/
Tests: 55/55 passing (32 Phase 1 + 23 Phase 2-5)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Unify reward system with polymorphic RewardEntry type
Replace all ItemEntry[] JSONB columns with RewardEntry[] across the
entire platform. RewardEntry uses a polymorphic { type, id, count }
shape instead of the old { definitionId, quantity }.
This means a single column handles all reward types — items, entities,
and future types (points, external goods) — without ever needing to
add new columns.
Changes:
- Add src/lib/rewards.ts with RewardEntry type, grantRewards() and
deductCosts() dispatch functions, filterByType() helper
- Update all 8 schema files (shop, lottery, mail, exchange, check-in,
collection, cdkey, entity) to use RewardEntry[] type annotations
- Update itemService.grantItems/deductItems to accept both
RewardEntry { id, count } and legacy { definitionId, quantity }
- Update all 8 module services, validators, routes, and types to use
the new RewardEntry format
- Update all test files with new { type: "item", id, count } format
- No schema migration needed (JSONB columns, type change is TS-only)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>1 parent 01ddfe9 commit 7611d42
74 files changed
Lines changed: 18629 additions & 225 deletions
File tree
- apps
- admin
- messages
- src
- components
- entity
- hooks
- lib/types
- routes/_dashboard/entity
- formations
- schemas
- $schemaId
- blueprints
- $blueprintId
- skins
- server
- drizzle
- meta
- src
- lib
- modules
- cdkey
- check-in
- collection
- entity
- exchange
- item
- lottery
- mail
- shop
- schema
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
114 | 114 | | |
115 | 115 | | |
116 | 116 | | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
117 | 121 | | |
118 | 122 | | |
119 | 123 | | |
| |||
758 | 762 | | |
759 | 763 | | |
760 | 764 | | |
761 | | - | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
| 838 | + | |
762 | 839 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
114 | 114 | | |
115 | 115 | | |
116 | 116 | | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
117 | 121 | | |
118 | 122 | | |
119 | 123 | | |
| |||
758 | 762 | | |
759 | 763 | | |
760 | 764 | | |
761 | | - | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
| 838 | + | |
762 | 839 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| 16 | + | |
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
| |||
39 | 40 | | |
40 | 41 | | |
41 | 42 | | |
| 43 | + | |
42 | 44 | | |
43 | 45 | | |
44 | 46 | | |
| |||
0 commit comments