Implement Workstream F1: me.get and me.setupProfile procedures

- Add me.get procedure returning user profile with needsSetup flag
- Add me.setupProfile procedure for initial profile setup after signup
- Add nonEmptyString/optionalString schema helpers with tests
- Use Web Crypto API (SubtleCrypto) for Cloudflare Workers compatibility
- Use @formatjs/intl-durationformat for duration formatting
- Remove node:crypto dependency from crypto utilities

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
RevIQ
2026-01-09 16:29:41 +08:00
parent 93851afe38
commit 860d791125
16 changed files with 205 additions and 61 deletions

View File

@@ -105,14 +105,50 @@ const verifyAuthentication = os.auth.webauthn.verifyAuthentication
});
// Me procedures
const meGet = os.me.get.use(authMiddleware).handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
const meGet = os.me.get.use(authMiddleware).handler(async ({ context }) => {
const user = await context.db
.selectFrom("users")
.select([
"id",
"email",
"display_name",
"full_name",
"phone_number",
"avatar_url",
"email_verified_at",
"is_superuser",
])
.where("id", "=", context.user.id)
.executeTakeFirstOrThrow();
return {
id: user.id,
email: user.email,
displayName: user.display_name,
fullName: user.full_name,
phoneNumber: user.phone_number,
avatarUrl: user.avatar_url,
emailVerified: user.email_verified_at !== null,
needsSetup: user.display_name === null,
isSuperuser: user.is_superuser,
};
});
const setupProfile = os.me.setupProfile
.use(authMiddleware)
.handler(async () => {
throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" });
.handler(async ({ input, context }) => {
const { displayName, fullName, phoneNumber } = input;
await context.db
.updateTable("users")
.set({
display_name: displayName,
full_name: fullName ?? null,
phone_number: phoneNumber ?? null,
updated_at: new Date(),
})
.where("id", "=", context.user.id)
.execute();
});
const updateProfile = os.me.updateProfile