start on statuses table list thing

This commit is contained in:
2025-09-04 16:40:16 -05:00
parent 56ea3e0904
commit 9e1d40333c
19 changed files with 498 additions and 125 deletions

View File

@@ -21,8 +21,8 @@ export const getUser = query(async (ctx) => {
if (!user) throw new ConvexError('User not found.');
const image: Id<'_storage'> | null =
typeof user.image === 'string' && user.image.length > 0
? user.image as Id<'_storage'>
: null
? (user.image as Id<'_storage'>)
: null;
return {
id: user._id,
email: user.email ?? null,
@@ -56,7 +56,7 @@ export const updateUserEmail = mutation({
if (!user) throw new ConvexError('User not found.');
await ctx.db.patch(userId, { email });
return { success: true };
}
},
});
export const updateUserImage = mutation({
@@ -70,8 +70,7 @@ export const updateUserImage = mutation({
if (!user) throw new ConvexError('User not found.');
const oldImage = user.image as Id<'_storage'> | undefined;
await ctx.db.patch(userId, { image: storageId });
if (oldImage && oldImage !== storageId)
await ctx.storage.delete(oldImage);
if (oldImage && oldImage !== storageId) await ctx.storage.delete(oldImage);
return { success: true };
},
});
@@ -94,14 +93,14 @@ export const updateUserPassword = action({
currentPassword: v.string(),
newPassword: v.string(),
},
handler: async (ctx, {currentPassword, newPassword}) => {
handler: async (ctx, { currentPassword, newPassword }) => {
const userId = await getAuthUserId(ctx);
if (!userId) throw new ConvexError('Not authenticated.');
const user = await ctx.runQuery(api.auth.getUser);
if (!user?.email) throw new ConvexError('User not found.');
const verified = await retrieveAccount(ctx, {
provider: 'password',
account: { id: user.email, secret: currentPassword }
account: { id: user.email, secret: currentPassword },
});
if (!verified) throw new ConvexError('Current password is incorrect.');
@@ -110,9 +109,9 @@ export const updateUserPassword = action({
await modifyAccountCredentials(ctx, {
provider: 'password',
account: { id: user.email, secret: newPassword }
account: { id: user.email, secret: newPassword },
});
return { success: true };
},
})
});

View File

@@ -17,14 +17,14 @@ export default defineSchema({
phoneVerificationTime: v.optional(v.number()),
isAnonymous: v.optional(v.boolean()),
})
.index("email", ["email"])
.index("phone", ["phone"]),
.index('email', ['email'])
.index('phone', ['phone']),
statuses: defineTable({
userId: v.id('users'),
message: v.string(),
updatedAt: v.number(),
updatedBy: v.id('users'),
})
.index('by_user', ['userId'])
.index('by_user_updatedAt', ['userId', 'updatedAt']),
.index('by_user', ['userId'])
.index('by_user_updatedAt', ['userId', 'updatedAt']),
});

View File

@@ -11,22 +11,16 @@ import type { MutationCtx, QueryCtx } from './_generated/server';
type RWCtx = MutationCtx | QueryCtx;
// CHANGED: typed helpers
const ensureUser = async (
ctx: RWCtx,
userId: Id<'users'>,
) => {
const ensureUser = async (ctx: RWCtx, userId: Id<'users'>) => {
const user = await ctx.db.get(userId);
if (!user) throw new ConvexError('User not found.');
return user;
};
const latestStatusForOwner = async (
ctx: RWCtx,
ownerId: Id<'users'>,
) => {
const latestStatusForOwner = async (ctx: RWCtx, ownerId: Id<'users'>) => {
const [latest] = await ctx.db
.query('statuses')
.withIndex('by_user_updatedAt', q => q.eq('userId', ownerId))
.withIndex('by_user_updatedAt', (q) => q.eq('userId', ownerId))
.order('desc')
.take(1);
return latest as Doc<'statuses'> | null;
@@ -180,7 +174,7 @@ export const listHistoryByUser = query({
return await ctx.db
.query('statuses')
.withIndex('by_user_updatedAt', q => q.eq('userId', userId))
.withIndex('by_user_updatedAt', (q) => q.eq('userId', userId))
.order('desc')
.paginate(paginationOpts);
},