feat(platform): harden access scoping and delivery baseline
This commit is contained in:
@@ -40,6 +40,114 @@ function createAdminCaller(db: Record<string, unknown>) {
|
||||
}
|
||||
|
||||
describe("holiday calendar router", () => {
|
||||
it("lists holiday calendars with assistant-facing detail formatting", async () => {
|
||||
const db = {
|
||||
holidayCalendar: {
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{
|
||||
id: "cal_by",
|
||||
name: "Bayern Feiertage",
|
||||
scopeType: "STATE",
|
||||
stateCode: "BY",
|
||||
isActive: true,
|
||||
priority: 10,
|
||||
country: { id: "country_de", code: "DE", name: "Deutschland" },
|
||||
metroCity: null,
|
||||
_count: { entries: 2 },
|
||||
entries: [
|
||||
{
|
||||
id: "entry_1",
|
||||
date: new Date("2026-01-06T00:00:00.000Z"),
|
||||
name: "Heilige Drei Koenige",
|
||||
isRecurringAnnual: true,
|
||||
source: "state",
|
||||
},
|
||||
],
|
||||
},
|
||||
]),
|
||||
},
|
||||
};
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
const result = await caller.listCalendarsDetail({
|
||||
countryCode: "DE",
|
||||
scopeType: "STATE",
|
||||
includeInactive: true,
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
count: 1,
|
||||
calendars: [
|
||||
expect.objectContaining({
|
||||
id: "cal_by",
|
||||
name: "Bayern Feiertage",
|
||||
scopeType: "STATE",
|
||||
stateCode: "BY",
|
||||
entryCount: 2,
|
||||
country: { id: "country_de", code: "DE", name: "Deutschland" },
|
||||
entries: [
|
||||
expect.objectContaining({
|
||||
id: "entry_1",
|
||||
date: "2026-01-06",
|
||||
name: "Heilige Drei Koenige",
|
||||
isRecurringAnnual: true,
|
||||
source: "state",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("resolves a holiday calendar by identifier with assistant-facing detail formatting", async () => {
|
||||
const db = {
|
||||
holidayCalendar: {
|
||||
findUnique: vi.fn().mockResolvedValue(null),
|
||||
findFirst: vi
|
||||
.fn()
|
||||
.mockResolvedValueOnce({
|
||||
id: "cal_augsburg",
|
||||
name: "Augsburg lokal",
|
||||
scopeType: "CITY",
|
||||
stateCode: null,
|
||||
isActive: true,
|
||||
priority: 5,
|
||||
country: { id: "country_de", code: "DE", name: "Deutschland" },
|
||||
metroCity: { id: "city_augsburg", name: "Augsburg" },
|
||||
entries: [
|
||||
{
|
||||
id: "entry_1",
|
||||
date: new Date("2026-08-08T00:00:00.000Z"),
|
||||
name: "Friedensfest lokal",
|
||||
isRecurringAnnual: true,
|
||||
source: "manual",
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
const result = await caller.getCalendarByIdentifierDetail({ identifier: "Augsburg lokal" });
|
||||
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
id: "cal_augsburg",
|
||||
name: "Augsburg lokal",
|
||||
scopeType: "CITY",
|
||||
entryCount: 1,
|
||||
metroCity: { id: "city_augsburg", name: "Augsburg" },
|
||||
entries: [
|
||||
expect.objectContaining({
|
||||
id: "entry_1",
|
||||
date: "2026-08-08",
|
||||
name: "Friedensfest lokal",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("merges built-in and scoped custom holidays in preview", async () => {
|
||||
const db = {
|
||||
country: {
|
||||
@@ -106,6 +214,164 @@ describe("holiday calendar router", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("formats preview results for assistant consumption", async () => {
|
||||
const db = {
|
||||
country: {
|
||||
findUnique: vi.fn().mockResolvedValue({ id: "country_de", code: "DE", name: "Deutschland" }),
|
||||
},
|
||||
metroCity: {
|
||||
findUnique: vi.fn().mockResolvedValue({ id: "city_augsburg", name: "Augsburg", countryId: "country_de" }),
|
||||
},
|
||||
holidayCalendar: {
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{
|
||||
id: "cal_city",
|
||||
name: "Augsburg lokal",
|
||||
scopeType: "CITY",
|
||||
priority: 10,
|
||||
createdAt: new Date("2026-01-01T00:00:00.000Z"),
|
||||
entries: [
|
||||
{
|
||||
id: "entry_1",
|
||||
date: new Date("2020-08-08T00:00:00.000Z"),
|
||||
name: "Friedensfest lokal",
|
||||
isRecurringAnnual: true,
|
||||
source: "manual",
|
||||
},
|
||||
],
|
||||
},
|
||||
]),
|
||||
},
|
||||
};
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
const result = await caller.previewResolvedHolidaysDetail({
|
||||
countryId: "country_de",
|
||||
metroCityId: "city_augsburg",
|
||||
year: 2026,
|
||||
});
|
||||
|
||||
expect(result.locationContext).toEqual({
|
||||
countryId: "country_de",
|
||||
countryCode: "DE",
|
||||
stateCode: null,
|
||||
metroCityId: "city_augsburg",
|
||||
metroCity: "Augsburg",
|
||||
year: 2026,
|
||||
});
|
||||
expect(result.summary.byScope).toEqual(
|
||||
expect.arrayContaining([expect.objectContaining({ scope: "CITY" })]),
|
||||
);
|
||||
expect(result.holidays).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
date: "2026-08-08",
|
||||
name: "Friedensfest lokal",
|
||||
scope: "CITY",
|
||||
calendarName: "Augsburg lokal",
|
||||
sourceType: "CUSTOM",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("formats resolved holidays by region for assistant consumption", async () => {
|
||||
const db = {
|
||||
holidayCalendar: {
|
||||
findMany: vi.fn().mockResolvedValue([]),
|
||||
},
|
||||
};
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
const result = await caller.resolveHolidaysDetail({
|
||||
countryCode: "DE",
|
||||
stateCode: "BY",
|
||||
periodStart: new Date("2026-01-01T00:00:00.000Z"),
|
||||
periodEnd: new Date("2026-12-31T00:00:00.000Z"),
|
||||
});
|
||||
|
||||
expect(result.locationContext).toEqual({
|
||||
countryId: null,
|
||||
countryCode: "DE",
|
||||
federalState: "BY",
|
||||
metroCityId: null,
|
||||
metroCity: null,
|
||||
});
|
||||
expect(result.count).toBeGreaterThan(0);
|
||||
expect(result.summary.byScope).toEqual(
|
||||
expect.arrayContaining([expect.objectContaining({ scope: "STATE" })]),
|
||||
);
|
||||
expect(result.holidays).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ name: "Heilige Drei Könige", date: "2026-01-06", scope: "STATE" }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("formats resolved holidays for a resource including local city holidays", async () => {
|
||||
const db = {
|
||||
resource: {
|
||||
findUnique: vi.fn().mockResolvedValue({
|
||||
id: "res_1",
|
||||
eid: "bruce.banner",
|
||||
displayName: "Bruce Banner",
|
||||
federalState: "BY",
|
||||
countryId: "country_de",
|
||||
metroCityId: "city_augsburg",
|
||||
country: { code: "DE", name: "Deutschland" },
|
||||
metroCity: { name: "Augsburg" },
|
||||
}),
|
||||
},
|
||||
holidayCalendar: {
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{
|
||||
id: "cal_city",
|
||||
name: "Augsburg lokal",
|
||||
scopeType: "CITY",
|
||||
priority: 5,
|
||||
createdAt: new Date("2026-01-01T00:00:00.000Z"),
|
||||
entries: [
|
||||
{
|
||||
id: "entry_1",
|
||||
date: new Date("2020-08-08T00:00:00.000Z"),
|
||||
name: "Augsburger Friedensfest",
|
||||
isRecurringAnnual: true,
|
||||
source: "manual",
|
||||
},
|
||||
],
|
||||
},
|
||||
]),
|
||||
},
|
||||
};
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
const result = await caller.resolveResourceHolidaysDetail({
|
||||
resourceId: "res_1",
|
||||
periodStart: new Date("2026-01-01T00:00:00.000Z"),
|
||||
periodEnd: new Date("2026-12-31T00:00:00.000Z"),
|
||||
});
|
||||
|
||||
expect(result.resource).toEqual(
|
||||
expect.objectContaining({
|
||||
eid: "bruce.banner",
|
||||
federalState: "BY",
|
||||
metroCity: "Augsburg",
|
||||
}),
|
||||
);
|
||||
expect(result.summary.byScope).toEqual(
|
||||
expect.arrayContaining([expect.objectContaining({ scope: "CITY" })]),
|
||||
);
|
||||
expect(result.holidays).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
name: "Augsburger Friedensfest",
|
||||
date: "2026-08-08",
|
||||
scope: "CITY",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects duplicate calendar scopes on create", async () => {
|
||||
const db = {
|
||||
country: {
|
||||
|
||||
Reference in New Issue
Block a user