refactor: Abbreviate item rarity values from full names to single-letter codes across the application.
All checks were successful
Deploy to Production / test (push) Successful in 40s

This commit is contained in:
syntaxbullet
2026-02-06 13:00:41 +01:00
parent db4e7313c3
commit 1929f0dd1f
10 changed files with 37 additions and 43 deletions

View File

@@ -23,7 +23,7 @@ export const renderWizard = (userId: string, isDraft = true) => {
draft = {
name: "New Item",
description: "No description",
rarity: "Common",
rarity: "C",
type: ItemType.MATERIAL,
price: null,
iconUrl: "",

View File

@@ -87,7 +87,7 @@ export const getDetailsModal = (current: DraftItem) => {
modal.addComponents(
new ActionRowBuilder<TextInputBuilder>().addComponents(new TextInputBuilder().setCustomId("name").setLabel("Name").setValue(current.name).setStyle(TextInputStyle.Short).setRequired(true)),
new ActionRowBuilder<TextInputBuilder>().addComponents(new TextInputBuilder().setCustomId("desc").setLabel("Description").setValue(current.description).setStyle(TextInputStyle.Paragraph).setRequired(false)),
new ActionRowBuilder<TextInputBuilder>().addComponents(new TextInputBuilder().setCustomId("rarity").setLabel("Rarity").setValue(current.rarity).setStyle(TextInputStyle.Short).setPlaceholder("Common, Rare, Legendary...").setRequired(true))
new ActionRowBuilder<TextInputBuilder>().addComponents(new TextInputBuilder().setCustomId("rarity").setLabel("Rarity").setValue(current.rarity).setStyle(TextInputStyle.Short).setPlaceholder("C, R, SR, SSR").setRequired(true))
);
return modal;
};

View File

@@ -59,7 +59,7 @@ export const items = pgTable('items', {
id: serial('id').primaryKey(),
name: varchar('name', { length: 255 }).unique().notNull(),
description: text('description'),
rarity: varchar('rarity', { length: 20 }).default('Common'),
rarity: varchar('rarity', { length: 20 }).default('C'),
// Economy & Visuals
type: varchar('type', { length: 50 }).notNull().default('MATERIAL'),

View File

@@ -16,7 +16,7 @@ import type { ItemType } from "@shared/lib/constants";
export interface CreateItemDTO {
name: string;
description?: string | null;
rarity?: 'Common' | 'Uncommon' | 'Rare' | 'Epic' | 'Legendary';
rarity?: 'C' | 'R' | 'SR' | 'SSR';
type: 'MATERIAL' | 'CONSUMABLE' | 'EQUIPMENT' | 'QUEST';
price?: bigint | null;
iconUrl: string;
@@ -27,7 +27,7 @@ export interface CreateItemDTO {
export interface UpdateItemDTO {
name?: string;
description?: string | null;
rarity?: 'Common' | 'Uncommon' | 'Rare' | 'Epic' | 'Legendary';
rarity?: 'C' | 'R' | 'SR' | 'SSR';
type?: 'MATERIAL' | 'CONSUMABLE' | 'EQUIPMENT' | 'QUEST';
price?: bigint | null;
iconUrl?: string;
@@ -122,7 +122,7 @@ export const itemsService = {
.values({
name: data.name,
description: data.description ?? null,
rarity: data.rarity ?? 'Common',
rarity: data.rarity ?? 'C',
type: data.type,
price: data.price ?? null,
iconUrl: data.iconUrl,

View File

@@ -39,7 +39,7 @@ import { Loader2, Coins, FileText, Image, Zap } from "lucide-react";
const itemFormSchema = z.object({
name: z.string().min(1, "Name is required").max(255, "Name is too long"),
description: z.string().optional().nullable(),
rarity: z.enum(["Common", "Uncommon", "Rare", "Epic", "Legendary"]),
rarity: z.enum(["C", "R", "SR", "SSR"]),
type: z.enum(["MATERIAL", "CONSUMABLE", "EQUIPMENT", "QUEST"]),
price: z.string().optional().nullable(),
consume: z.boolean(),
@@ -62,11 +62,10 @@ const ITEM_TYPES = [
];
const RARITIES = [
{ value: "Common", label: "Common" },
{ value: "Uncommon", label: "Uncommon" },
{ value: "Rare", label: "Rare" },
{ value: "Epic", label: "Epic" },
{ value: "Legendary", label: "Legendary" },
{ value: "C", label: "C" },
{ value: "R", label: "R" },
{ value: "SR", label: "SR" },
{ value: "SSR", label: "SSR" },
];
export function ItemForm({ initialData, onSuccess, onCancel }: ItemFormProps) {
@@ -81,7 +80,7 @@ export function ItemForm({ initialData, onSuccess, onCancel }: ItemFormProps) {
defaultValues: {
name: "",
description: "",
rarity: "Common" as const,
rarity: "C" as const,
type: "MATERIAL" as const,
price: "",
consume: false,
@@ -95,7 +94,7 @@ export function ItemForm({ initialData, onSuccess, onCancel }: ItemFormProps) {
form.reset({
name: initialData.name,
description: initialData.description || "",
rarity: (initialData.rarity as FormValues["rarity"]) || "Common",
rarity: (initialData.rarity as FormValues["rarity"]) || "C",
type: (initialData.type as FormValues["type"]) || "MATERIAL",
price: initialData.price ? String(initialData.price) : "",
consume: initialData.usageData?.consume ?? false,

View File

@@ -31,11 +31,10 @@ const ITEM_TYPES = [
];
const RARITIES = [
{ value: "Common", label: "Common", color: "text-zinc-400" },
{ value: "Uncommon", label: "Uncommon", color: "text-green-400" },
{ value: "Rare", label: "Rare", color: "text-blue-400" },
{ value: "Epic", label: "Epic", color: "text-purple-400" },
{ value: "Legendary", label: "Legendary", color: "text-amber-400" },
{ value: "C", label: "C", color: "text-zinc-400" },
{ value: "R", label: "R", color: "text-blue-400" },
{ value: "SR", label: "SR", color: "text-purple-400" },
{ value: "SSR", label: "SSR", color: "text-amber-400" },
];
export function ItemsFilter({ filters, onFilterChange, onClearFilters }: ItemsFilterProps) {

View File

@@ -85,9 +85,9 @@ export function ItemsTable({
case 'type':
return direction * (a.type || '').localeCompare(b.type || '');
case 'rarity': {
const rarityOrder = ['Common', 'Uncommon', 'Rare', 'Epic', 'Legendary'];
const aIndex = rarityOrder.indexOf(a.rarity || 'Common');
const bIndex = rarityOrder.indexOf(b.rarity || 'Common');
const rarityOrder = ['C', 'R', 'SR', 'SSR'];
const aIndex = rarityOrder.indexOf(a.rarity || 'C');
const bIndex = rarityOrder.indexOf(b.rarity || 'C');
return direction * (aIndex - bIndex);
}
case 'price': {
@@ -280,7 +280,7 @@ export function ItemsTable({
{/* Rarity (hidden on mobile) */}
<div className="hidden md:block">
<RarityBadge rarity={item.rarity || 'Common'} size="sm" />
<RarityBadge rarity={item.rarity || 'C'} size="sm" />
</div>
{/* Price (hidden on mobile) */}
@@ -297,7 +297,7 @@ export function ItemsTable({
{/* Mobile: badges */}
<div className="flex md:hidden items-center gap-2">
<RarityBadge rarity={item.rarity || 'Common'} size="sm" />
<RarityBadge rarity={item.rarity || 'C'} size="sm" />
</div>
{/* Actions */}

View File

@@ -5,7 +5,7 @@
import { cn } from "@/lib/utils";
export type Rarity = 'Common' | 'Uncommon' | 'Rare' | 'Epic' | 'Legendary';
export type Rarity = 'C' | 'R' | 'SR' | 'SSR';
interface RarityBadgeProps {
rarity: Rarity | string;
@@ -14,23 +14,19 @@ interface RarityBadgeProps {
}
const rarityStyles: Record<Rarity, { bg: string; text: string; glow?: string }> = {
Common: {
C: {
bg: 'bg-zinc-600/30',
text: 'text-zinc-300',
},
Uncommon: {
bg: 'bg-emerald-600/30',
text: 'text-emerald-400',
},
Rare: {
R: {
bg: 'bg-blue-600/30',
text: 'text-blue-400',
},
Epic: {
SR: {
bg: 'bg-purple-600/30',
text: 'text-purple-400',
},
Legendary: {
SSR: {
bg: 'bg-amber-600/30',
text: 'text-amber-400',
glow: 'shadow-[0_0_10px_rgba(251,191,36,0.4)]',
@@ -44,7 +40,7 @@ const sizeStyles = {
};
export function RarityBadge({ rarity, className, size = 'md' }: RarityBadgeProps) {
const validRarity = (rarity in rarityStyles ? rarity : 'Common') as Rarity;
const validRarity = (rarity in rarityStyles ? rarity : 'C') as Rarity;
const styles = rarityStyles[validRarity];
return (

View File

@@ -41,7 +41,7 @@ export interface ItemsResponse {
export interface CreateItemData {
name: string;
description?: string | null;
rarity?: 'Common' | 'Uncommon' | 'Rare' | 'Epic' | 'Legendary';
rarity?: 'C' | 'R' | 'SR' | 'SSR';
type: 'MATERIAL' | 'CONSUMABLE' | 'EQUIPMENT' | 'QUEST';
price?: string | null;
iconUrl?: string;

View File

@@ -28,7 +28,7 @@ let mockItems: MockItem[] = [
id: 1,
name: "Health Potion",
description: "Restores health",
rarity: "Common",
rarity: "C",
type: "CONSUMABLE",
price: 100n,
iconUrl: "/assets/items/1.png",
@@ -39,7 +39,7 @@ let mockItems: MockItem[] = [
id: 2,
name: "Iron Sword",
description: "A basic sword",
rarity: "Uncommon",
rarity: "R",
type: "EQUIPMENT",
price: 500n,
iconUrl: "/assets/items/2.png",
@@ -96,7 +96,7 @@ mock.module("@shared/modules/items/items.service", () => ({
id: mockIdCounter++,
name: data.name,
description: data.description ?? null,
rarity: data.rarity ?? "Common",
rarity: data.rarity ?? "C",
type: data.type,
price: data.price ?? null,
iconUrl: data.iconUrl,
@@ -154,7 +154,7 @@ describe("Items API", () => {
id: 1,
name: "Health Potion",
description: "Restores health",
rarity: "Common",
rarity: "C",
type: "CONSUMABLE",
price: 100n,
iconUrl: "/assets/items/1.png",
@@ -165,7 +165,7 @@ describe("Items API", () => {
id: 2,
name: "Iron Sword",
description: "A basic sword",
rarity: "Uncommon",
rarity: "R",
type: "EQUIPMENT",
price: 500n,
iconUrl: "/assets/items/2.png",
@@ -217,11 +217,11 @@ describe("Items API", () => {
});
test("should filter items by rarity", async () => {
const response = await fetch(`${baseUrl}/api/items?rarity=Common`);
const response = await fetch(`${baseUrl}/api/items?rarity=C`);
expect(response.status).toBe(200);
const data = (await response.json()) as { items: MockItem[]; total: number };
expect(data.items.every((item) => item.rarity === "Common")).toBe(true);
expect(data.items.every((item) => item.rarity === "C")).toBe(true);
});
});
@@ -255,7 +255,7 @@ describe("Items API", () => {
const newItem = {
name: "Magic Staff",
description: "A powerful staff",
rarity: "Rare",
rarity: "SR",
type: "EQUIPMENT",
price: "1000",
iconUrl: "/assets/items/placeholder.png",