@mulingai-npm/redis 3.24.0 → 3.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/enums/redis-database.d.ts +2 -1
- package/dist/enums/redis-database.js +1 -0
- package/dist/managers/mulingstream-speaker-manager.d.ts +1 -0
- package/dist/managers/mulingstream-speaker-manager.js +4 -2
- package/dist/managers/user-profile-manager.d.ts +49 -0
- package/dist/managers/user-profile-manager.js +86 -0
- package/package.json +1 -1
|
@@ -7,4 +7,5 @@ var RedisDatabase;
|
|
|
7
7
|
RedisDatabase[RedisDatabase["MULINGSTREAM_CHUNK"] = 1] = "MULINGSTREAM_CHUNK";
|
|
8
8
|
RedisDatabase[RedisDatabase["MULINGSTREAM_SPEAKER"] = 2] = "MULINGSTREAM_SPEAKER";
|
|
9
9
|
RedisDatabase[RedisDatabase["CONTENT_DATA"] = 3] = "CONTENT_DATA";
|
|
10
|
+
RedisDatabase[RedisDatabase["ACCOUNT_DATA"] = 4] = "ACCOUNT_DATA";
|
|
10
11
|
})(RedisDatabase = exports.RedisDatabase || (exports.RedisDatabase = {}));
|
|
@@ -32,7 +32,8 @@ class MulingstreamSpeakerManager {
|
|
|
32
32
|
prompts: hash.prompts,
|
|
33
33
|
recordingsDuration: parseInt(hash.recordingsDuration, 10) || 0,
|
|
34
34
|
targetLanguages: JSON.parse(hash.targetLanguages || '[]'),
|
|
35
|
-
timestamp: hash.timestamp
|
|
35
|
+
timestamp: hash.timestamp,
|
|
36
|
+
isEmailVerified: hash.isEmailVerified === 'true'
|
|
36
37
|
};
|
|
37
38
|
}
|
|
38
39
|
serialize(data) {
|
|
@@ -46,7 +47,8 @@ class MulingstreamSpeakerManager {
|
|
|
46
47
|
prompts: data.prompts,
|
|
47
48
|
recordingsDuration: data.recordingsDuration.toString(),
|
|
48
49
|
targetLanguages: JSON.stringify(data.targetLanguages),
|
|
49
|
-
timestamp: data.timestamp
|
|
50
|
+
timestamp: data.timestamp,
|
|
51
|
+
isEmailVerified: data.isEmailVerified.toString()
|
|
50
52
|
};
|
|
51
53
|
if (data.roomUuid) {
|
|
52
54
|
result.roomUuid = data.roomUuid;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { RedisClient } from '../redis-client';
|
|
2
|
+
/**
|
|
3
|
+
* Cached user profile data - minimal data needed for quick lookups
|
|
4
|
+
*/
|
|
5
|
+
export interface CachedUserProfile {
|
|
6
|
+
userId: string;
|
|
7
|
+
email: string;
|
|
8
|
+
name: string | null;
|
|
9
|
+
isEmailVerified: boolean;
|
|
10
|
+
cachedAt: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Redis manager for caching user profile data
|
|
14
|
+
* Used to avoid expensive database queries on every request
|
|
15
|
+
*
|
|
16
|
+
* Cache invalidation should happen on:
|
|
17
|
+
* - Email verification
|
|
18
|
+
* - Profile update
|
|
19
|
+
* - Account deletion
|
|
20
|
+
*/
|
|
21
|
+
export declare class UserProfileManager {
|
|
22
|
+
private redisClient;
|
|
23
|
+
constructor(redisClient: RedisClient);
|
|
24
|
+
private buildKey;
|
|
25
|
+
/**
|
|
26
|
+
* Cache user profile data
|
|
27
|
+
*/
|
|
28
|
+
setUserProfile(profile: Omit<CachedUserProfile, 'cachedAt'>): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Get cached user profile
|
|
31
|
+
* Returns null if not cached (caller should fetch from DB and cache)
|
|
32
|
+
*/
|
|
33
|
+
getUserProfile(userId: string): Promise<CachedUserProfile | null>;
|
|
34
|
+
/**
|
|
35
|
+
* Check if user email is verified (quick lookup)
|
|
36
|
+
* Returns null if not cached
|
|
37
|
+
*/
|
|
38
|
+
isEmailVerified(userId: string): Promise<boolean | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Invalidate user profile cache
|
|
41
|
+
* Call this when profile data changes (verification, update, etc.)
|
|
42
|
+
*/
|
|
43
|
+
invalidateUserProfile(userId: string): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Update only the email verification status in cache
|
|
46
|
+
* More efficient than full invalidation when only verification changes
|
|
47
|
+
*/
|
|
48
|
+
updateEmailVerificationStatus(userId: string, isVerified: boolean): Promise<boolean>;
|
|
49
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UserProfileManager = void 0;
|
|
4
|
+
// Cache for 1 hour
|
|
5
|
+
const CACHE_EXPIRATION = 60 * 60;
|
|
6
|
+
/**
|
|
7
|
+
* Redis manager for caching user profile data
|
|
8
|
+
* Used to avoid expensive database queries on every request
|
|
9
|
+
*
|
|
10
|
+
* Cache invalidation should happen on:
|
|
11
|
+
* - Email verification
|
|
12
|
+
* - Profile update
|
|
13
|
+
* - Account deletion
|
|
14
|
+
*/
|
|
15
|
+
class UserProfileManager {
|
|
16
|
+
constructor(redisClient) {
|
|
17
|
+
this.redisClient = redisClient;
|
|
18
|
+
}
|
|
19
|
+
buildKey(userId) {
|
|
20
|
+
return `user:${userId}:profile`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Cache user profile data
|
|
24
|
+
*/
|
|
25
|
+
async setUserProfile(profile) {
|
|
26
|
+
const key = this.buildKey(profile.userId);
|
|
27
|
+
const data = {
|
|
28
|
+
...profile,
|
|
29
|
+
cachedAt: new Date().toISOString()
|
|
30
|
+
};
|
|
31
|
+
await this.redisClient.set(key, JSON.stringify(data));
|
|
32
|
+
await this.redisClient.expire(key, CACHE_EXPIRATION);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get cached user profile
|
|
36
|
+
* Returns null if not cached (caller should fetch from DB and cache)
|
|
37
|
+
*/
|
|
38
|
+
async getUserProfile(userId) {
|
|
39
|
+
const key = this.buildKey(userId);
|
|
40
|
+
const data = await this.redisClient.get(key);
|
|
41
|
+
if (data === null) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
return JSON.parse(data);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Invalid JSON, delete and return null
|
|
49
|
+
await this.redisClient.del(key);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Check if user email is verified (quick lookup)
|
|
55
|
+
* Returns null if not cached
|
|
56
|
+
*/
|
|
57
|
+
async isEmailVerified(userId) {
|
|
58
|
+
const profile = await this.getUserProfile(userId);
|
|
59
|
+
return profile ? profile.isEmailVerified : null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Invalidate user profile cache
|
|
63
|
+
* Call this when profile data changes (verification, update, etc.)
|
|
64
|
+
*/
|
|
65
|
+
async invalidateUserProfile(userId) {
|
|
66
|
+
const key = this.buildKey(userId);
|
|
67
|
+
await this.redisClient.del(key);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Update only the email verification status in cache
|
|
71
|
+
* More efficient than full invalidation when only verification changes
|
|
72
|
+
*/
|
|
73
|
+
async updateEmailVerificationStatus(userId, isVerified) {
|
|
74
|
+
const profile = await this.getUserProfile(userId);
|
|
75
|
+
if (profile === null) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
profile.isEmailVerified = isVerified;
|
|
79
|
+
profile.cachedAt = new Date().toISOString();
|
|
80
|
+
const key = this.buildKey(userId);
|
|
81
|
+
await this.redisClient.set(key, JSON.stringify(profile));
|
|
82
|
+
await this.redisClient.expire(key, CACHE_EXPIRATION);
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.UserProfileManager = UserProfileManager;
|