feat(private-room): connect moments feed
Docker Image / Build and Push Docker Image (push) Successful in 9m29s

This commit is contained in:
2026-07-08 16:29:08 +08:00
parent 77b496da2b
commit c46b9b4cdd
41 changed files with 3107 additions and 281 deletions
+4
View File
@@ -0,0 +1,4 @@
export * from "./private_room";
export * from "./private_room_moments_response";
export * from "./private_room_unlock_response";
export * from "./unlock_private_room_moment_request";
@@ -0,0 +1,102 @@
import { z } from "zod";
import {
arrayOrEmpty,
booleanOrFalse,
numberOrZero,
schemaOr,
stringOrEmpty,
stringOrNull,
} from "../nullable-defaults";
export const PrivateRoomProfileSchema = z.object({
characterId: stringOrEmpty,
displayName: stringOrEmpty,
authorName: stringOrEmpty,
avatarUrl: stringOrNull,
coverUrl: stringOrNull,
title: stringOrEmpty,
subtitle: stringOrEmpty,
});
export const PrivateRoomImageSchema = z.object({
url: stringOrNull,
type: stringOrEmpty,
locked: booleanOrFalse,
index: numberOrZero,
});
export const PrivateRoomLockDetailSchema = z.object({
locked: booleanOrFalse,
showContent: booleanOrFalse,
showUpgrade: booleanOrFalse,
reason: stringOrNull,
hint: stringOrNull,
actionLabel: stringOrNull,
type: stringOrNull,
requiredCredits: numberOrZero,
currentCredits: numberOrZero,
shortfallCredits: numberOrZero,
mediaCount: numberOrZero,
unlockCostPerImage: numberOrZero,
detail: z.unknown().nullable().default(null),
});
export const PrivateRoomAuthorSchema = z.object({
id: stringOrEmpty,
name: stringOrEmpty,
avatarUrl: stringOrNull,
});
export const PrivateRoomMomentSchema = z.object({
momentId: stringOrEmpty,
source: stringOrEmpty,
sourceId: stringOrEmpty,
characterId: stringOrEmpty,
author: schemaOr(PrivateRoomAuthorSchema, {
id: "",
name: "",
avatarUrl: null,
}),
createdAt: stringOrNull,
publishedAt: stringOrNull,
timeText: stringOrEmpty,
title: stringOrEmpty,
content: stringOrNull,
text: stringOrNull,
textPreview: stringOrEmpty,
mediaCount: numberOrZero,
images: arrayOrEmpty(PrivateRoomImageSchema),
locked: booleanOrFalse,
unlocked: booleanOrFalse,
unlockCost: numberOrZero,
unlockCostPerImage: numberOrZero,
requiredCredits: numberOrZero,
currency: stringOrEmpty,
lockDetail: schemaOr(PrivateRoomLockDetailSchema, {
locked: false,
showContent: false,
showUpgrade: false,
reason: null,
hint: null,
actionLabel: null,
type: null,
requiredCredits: 0,
currentCredits: 0,
shortfallCredits: 0,
mediaCount: 0,
unlockCostPerImage: 0,
detail: null,
}),
});
export type PrivateRoomProfileData = z.output<
typeof PrivateRoomProfileSchema
>;
export type PrivateRoomImageData = z.output<typeof PrivateRoomImageSchema>;
export type PrivateRoomLockDetailData = z.output<
typeof PrivateRoomLockDetailSchema
>;
export type PrivateRoomAuthorData = z.output<typeof PrivateRoomAuthorSchema>;
export type PrivateRoomMomentInput = z.input<typeof PrivateRoomMomentSchema>;
export type PrivateRoomMomentData = z.output<typeof PrivateRoomMomentSchema>;
@@ -0,0 +1,41 @@
import { z } from "zod";
import {
arrayOrEmpty,
booleanOrFalse,
numberOrZero,
schemaOr,
stringOrEmpty,
stringOrNull,
} from "../nullable-defaults";
import {
PrivateRoomMomentSchema,
PrivateRoomProfileSchema,
} from "./private_room";
export const PrivateRoomMomentsResponseSchema = z.object({
profile: schemaOr(PrivateRoomProfileSchema, {
characterId: "elio",
displayName: "Elio Silvestri",
authorName: "Elio Silvestri",
avatarUrl: null,
coverUrl: null,
title: "Elio Private room",
subtitle: "Join me, unlock my private room",
}),
items: arrayOrEmpty(PrivateRoomMomentSchema),
nextCursor: stringOrNull,
hasMore: booleanOrFalse,
creditBalance: numberOrZero,
unlockCostDefault: numberOrZero,
unlockCostPerImage: numberOrZero,
currency: stringOrEmpty,
source: stringOrEmpty,
});
export type PrivateRoomMomentsResponseInput = z.input<
typeof PrivateRoomMomentsResponseSchema
>;
export type PrivateRoomMomentsResponseData = z.output<
typeof PrivateRoomMomentsResponseSchema
>;
@@ -0,0 +1,36 @@
import { z } from "zod";
import { booleanOrFalse, numberOrZero, stringOrEmpty } from "../nullable-defaults";
import { PrivateRoomMomentSchema } from "./private_room";
export const PrivateRoomUnlockReasonSchema = z.enum([
"ok",
"already_unlocked",
"insufficient_credits",
"cost_changed",
"not_found",
"no_media",
"deduct_failed",
"ok_persist_failed",
]);
export const PrivateRoomUnlockResponseSchema =
PrivateRoomMomentSchema.extend({
reason: PrivateRoomUnlockReasonSchema.or(stringOrEmpty),
creditsCharged: numberOrZero,
creditBalance: numberOrZero,
previousCreditBalance: numberOrZero,
currentCredits: numberOrZero,
shortfallCredits: numberOrZero,
persisted: booleanOrFalse,
});
export type PrivateRoomUnlockReason = z.output<
typeof PrivateRoomUnlockReasonSchema
>;
export type PrivateRoomUnlockResponseInput = z.input<
typeof PrivateRoomUnlockResponseSchema
>;
export type PrivateRoomUnlockResponseData = z.output<
typeof PrivateRoomUnlockResponseSchema
>;
@@ -0,0 +1,14 @@
import { z } from "zod";
import { numberOrZero } from "../nullable-defaults";
export const UnlockPrivateRoomMomentRequestSchema = z.object({
expectedCost: numberOrZero,
});
export type UnlockPrivateRoomMomentRequestInput = z.input<
typeof UnlockPrivateRoomMomentRequestSchema
>;
export type UnlockPrivateRoomMomentRequestData = z.output<
typeof UnlockPrivateRoomMomentRequestSchema
>;