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:
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
import type { OrgRole } from "@reviq/db-schema";
|
||||
import { DurationFormat } from "@formatjs/intl-durationformat";
|
||||
import { ServerClient } from "postmark";
|
||||
import {
|
||||
BASE_URL,
|
||||
@@ -113,37 +114,24 @@ const sendEmail = async (params: SendEmailParams): Promise<EmailResult> => {
|
||||
|
||||
// ===== Template Helpers =====
|
||||
|
||||
const formatExpiryHours = (hours: number): string => {
|
||||
if (hours === 1) {
|
||||
return "1 hour";
|
||||
}
|
||||
return `${hours} hours`;
|
||||
const durationFormatter = new DurationFormat("en", { style: "long" });
|
||||
|
||||
const formatExpiryHours = (hours: number): string =>
|
||||
durationFormatter.format({ hours });
|
||||
|
||||
const formatExpiryMinutes = (minutes: number): string =>
|
||||
durationFormatter.format({ minutes });
|
||||
|
||||
const formatExpiryDays = (days: number): string =>
|
||||
durationFormatter.format({ days });
|
||||
|
||||
const roleLabels: Record<OrgRole, string> = {
|
||||
owner: "Owner",
|
||||
admin: "Admin",
|
||||
member: "Member",
|
||||
};
|
||||
|
||||
const formatExpiryMinutes = (minutes: number): string => {
|
||||
if (minutes === 1) {
|
||||
return "1 minute";
|
||||
}
|
||||
return `${minutes} minutes`;
|
||||
};
|
||||
|
||||
const formatExpiryDays = (days: number): string => {
|
||||
if (days === 1) {
|
||||
return "1 day";
|
||||
}
|
||||
return `${days} days`;
|
||||
};
|
||||
|
||||
const formatRoleDisplay = (role: OrgRole): string => {
|
||||
switch (role) {
|
||||
case "owner":
|
||||
return "Owner";
|
||||
case "admin":
|
||||
return "Admin";
|
||||
case "member":
|
||||
return "Member";
|
||||
}
|
||||
};
|
||||
const formatRoleDisplay = (role: OrgRole): string => roleLabels[role];
|
||||
|
||||
/**
|
||||
* Get the correct article (a/an) for a role
|
||||
|
||||
Reference in New Issue
Block a user