feat: implement TASK-WP1-01 registration transaction

This commit is contained in:
suyx
2026-07-28 15:54:28 +08:00
parent 1bf7e42294
commit f467e7c09f
15 changed files with 2191 additions and 4 deletions
+89
View File
@@ -0,0 +1,89 @@
import { Type, type Static } from "@sinclair/typebox";
const uuidPattern = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$";
const isoTimestampPattern = "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{3}Z$";
const emailPattern = "^[^@\\s]{1,128}@[^@\\s]{1,190}$";
export const RegistrationSendRequestSchema = Type.Object(
{
email: Type.String({ maxLength: 320, pattern: emailPattern }),
invite_code: Type.String({ maxLength: 160, minLength: 8 }),
},
{ additionalProperties: false, $id: "RegistrationSendRequest" },
);
export const RegistrationSendResponseSchema = Type.Object(
{
challenge_expires_at: Type.String({ pattern: isoTimestampPattern }),
registration_id: Type.String({ pattern: uuidPattern }),
resend_available_at: Type.String({ pattern: isoTimestampPattern }),
status: Type.Literal("verification_sent"),
},
{ additionalProperties: false, $id: "RegistrationSendResponse" },
);
export const RegistrationCompleteRequestSchema = Type.Object(
{
creator_name: Type.String({ maxLength: 80, minLength: 1 }),
privacy_consent_accepted: Type.Boolean(),
privacy_notice_version: Type.String({ maxLength: 80, minLength: 1 }),
registration_id: Type.String({ pattern: uuidPattern }),
social_id: Type.String({ maxLength: 80, minLength: 1 }),
verification_code: Type.String({ pattern: "^[0-9]{6}$" }),
},
{ additionalProperties: false, $id: "RegistrationCompleteRequest" },
);
export const RegistrationCompleteHeadersSchema = Type.Object(
{
"idempotency-key": Type.String({ maxLength: 200, minLength: 32, pattern: "^[A-Za-z0-9_-]+$" }),
},
{ additionalProperties: true, $id: "RegistrationCompleteHeaders" },
);
export const AuthenticatedUserSchema = Type.Object(
{
creator_name: Type.String({ maxLength: 80, minLength: 1 }),
role: Type.Literal("user"),
social_id: Type.String({ maxLength: 80, minLength: 1 }),
status: Type.Literal("active"),
user_id: Type.String({ pattern: uuidPattern }),
},
{ additionalProperties: false, $id: "AuthenticatedUser" },
);
export const CreditSummarySchema = Type.Object(
{
available_balance: Type.Integer(),
reserved_balance: Type.Integer({ minimum: 0 }),
},
{ additionalProperties: false, $id: "CreditSummary" },
);
export const RegistrationCompleteResponseSchema = Type.Object(
{
credits: Type.Ref(CreditSummarySchema),
session_expires_at: Type.String({ pattern: isoTimestampPattern }),
status: Type.Literal("registered"),
user: Type.Ref(AuthenticatedUserSchema),
},
{ additionalProperties: false, $id: "RegistrationCompleteResponse" },
);
export const UserSessionResponseSchema = Type.Object(
{
audience: Type.Literal("user"),
authenticated: Type.Literal(true),
credits: Type.Ref(CreditSummarySchema),
csrf_token: Type.String({ maxLength: 64, minLength: 43, pattern: "^[A-Za-z0-9_-]+$" }),
expires_at: Type.String({ pattern: isoTimestampPattern }),
user: Type.Ref(AuthenticatedUserSchema),
},
{ additionalProperties: false, $id: "UserSessionResponse" },
);
export type RegistrationSendRequest = Static<typeof RegistrationSendRequestSchema>;
export type RegistrationSendResponse = Static<typeof RegistrationSendResponseSchema>;
export type RegistrationCompleteRequest = Static<typeof RegistrationCompleteRequestSchema>;
export type RegistrationCompleteResponse = Static<typeof RegistrationCompleteResponseSchema>;
export type UserSessionResponse = Static<typeof UserSessionResponseSchema>;