feat : update
CI / Verify (push) Successful in 1m5s
CI / Build immutable images and deploy (push) Successful in 2m2s

This commit is contained in:
2026-09-04 22:02:57 +07:00 Unverified
parent 513e37ad83
commit 5f74ce1de6
10 changed files with 3833 additions and 44 deletions
+20 -1
View File
@@ -1,7 +1,7 @@
import { describe, expect, it } from "vitest";
import { calculateTeamMetrics } from "@/lib/guides/calculations";
import { artifactSectionSchema, constellationSectionSchema, createGuideSchema, teamSectionSchema, updateGuideSchema, weaponSectionSchema } from "@/lib/guides/schemas";
import { artifactSectionSchema, constellationSectionSchema, createGuideSchema, extraSectionSchema, teamSectionSchema, updateGuideSchema, weaponSectionSchema } from "@/lib/guides/schemas";
import {
recommendedStatElement,
recommendedStatIconName,
@@ -138,6 +138,25 @@ describe("structured guide validation", () => {
const input = { expectedVersion: 1, teams: [{ title: "Test", rotationSeconds: 20, combo: "E > Q", members: ["1", "2", "3", "4"].map(member) }] };
expect(teamSectionSchema.safeParse(input).success).toBe(true);
});
it("accepts Extra card colors only as a valid pair", () => {
const row = {
mediaId: null,
heading: "Extra card",
body: "First line\nSecond line",
percent: null,
};
const input = (colors: { backgroundColor: string | null; textColor: string | null }) => ({
expectedVersion: 1,
sections: [{ title: "Extra", rows: [{ ...row, ...colors }] }],
});
expect(extraSectionSchema.safeParse(input({ backgroundColor: null, textColor: null })).success).toBe(true);
expect(extraSectionSchema.safeParse(input({ backgroundColor: "#24232C", textColor: "#F5F2EA" })).success).toBe(true);
expect(extraSectionSchema.safeParse({ expectedVersion: 1, sections: [{ title: "Extra", rows: [row] }] }).success).toBe(true);
expect(extraSectionSchema.safeParse(input({ backgroundColor: "#24232C", textColor: null })).success).toBe(false);
expect(extraSectionSchema.safeParse(input({ backgroundColor: "red", textColor: "#F5F2EA" })).success).toBe(false);
});
});
describe("Team Calc", () => {
+15 -6
View File
@@ -131,16 +131,25 @@ export const teamSectionSchema = z.strictObject({
})).max(30),
});
const hexColor = z.string().regex(/^#[0-9a-fA-F]{6}$/, "กรุณาเลือกสีที่ถูกต้อง");
const extraRowSchema = z.strictObject({
mediaId: z.string().uuid().nullable(),
heading: z.string().trim().min(1).max(200),
body: z.string().trim().max(2_000),
percent: percent.nullable(),
backgroundColor: hexColor.nullable().default(null),
textColor: hexColor.nullable().default(null),
}).refine(
(row) => (row.backgroundColor === null) === (row.textColor === null),
{ message: "ต้องเลือกสีพื้นหลังและสีข้อความพร้อมกัน", path: ["backgroundColor"] },
);
export const extraSectionSchema = z.strictObject({
expectedVersion: z.number().int().positive(),
sections: z.array(z.strictObject({
title: z.string().trim().min(1).max(160),
rows: z.array(z.strictObject({
mediaId: z.string().uuid().nullable(),
heading: z.string().trim().min(1).max(200),
body: z.string().trim().max(2_000),
percent: percent.nullable(),
})).max(50),
rows: z.array(extraRowSchema).max(50),
})).max(20),
});