feat(M08-A): 接入顾客端权益明细
This commit is contained in:
@@ -18,7 +18,7 @@ const listSchema = z.object({
|
||||
});
|
||||
|
||||
export interface MemberRouteOptions {
|
||||
service: Pick<MemberProfileService, 'listMembers' | 'getMember' | 'getMyProfile'>;
|
||||
service: Pick<MemberProfileService, 'listMembers' | 'getMember' | 'getMyProfile' | 'getMyBenefits'>;
|
||||
authRepository: Pick<AuthRepository, 'validateSession'>;
|
||||
accessControl: { getAccessProfile(tenantId: string, userId: string): Promise<AccessProfile> };
|
||||
jwtSecret: string;
|
||||
@@ -29,31 +29,26 @@ export async function registerMemberRoutes(
|
||||
options: MemberRouteOptions
|
||||
): Promise<void> {
|
||||
app.get('/app-api/profile', async (request, reply) => {
|
||||
const auth = await authenticateAccessToken(
|
||||
request.headers.authorization,
|
||||
options.authRepository,
|
||||
options.jwtSecret
|
||||
);
|
||||
if (!auth) {
|
||||
return reply.status(401).send({
|
||||
code: 'AUTH_SESSION_INVALID', message: 'Authentication required.', traceId: request.traceId
|
||||
});
|
||||
}
|
||||
const access = await options.accessControl.getAccessProfile(
|
||||
auth.session.tenantId,
|
||||
auth.session.user.id
|
||||
);
|
||||
if (!access.capabilities.includes('profile.read')) {
|
||||
return reply.status(403).send({
|
||||
code: 'PROFILE_READ_FORBIDDEN', message: 'Profile read permission is required.',
|
||||
traceId: request.traceId
|
||||
});
|
||||
}
|
||||
const auth = await requireProfileReader(request, reply, options);
|
||||
if (!auth) return;
|
||||
return handle(reply, request.traceId, async () => ({
|
||||
code: 0,
|
||||
data: await options.service.getMyProfile({
|
||||
tenantId: auth.session.tenantId,
|
||||
userId: auth.session.user.id
|
||||
tenantId: auth.tenantId,
|
||||
userId: auth.userId
|
||||
}),
|
||||
traceId: request.traceId
|
||||
}));
|
||||
});
|
||||
|
||||
app.get('/app-api/profile/benefits', async (request, reply) => {
|
||||
const auth = await requireProfileReader(request, reply, options);
|
||||
if (!auth) return;
|
||||
return handle(reply, request.traceId, async () => ({
|
||||
code: 0,
|
||||
data: await options.service.getMyBenefits({
|
||||
tenantId: auth.tenantId,
|
||||
userId: auth.userId
|
||||
}),
|
||||
traceId: request.traceId
|
||||
}));
|
||||
@@ -84,6 +79,36 @@ export async function registerMemberRoutes(
|
||||
});
|
||||
}
|
||||
|
||||
async function requireProfileReader(
|
||||
request: FastifyRequest,
|
||||
reply: FastifyReply,
|
||||
options: MemberRouteOptions
|
||||
): Promise<{ tenantId: string; userId: string } | null> {
|
||||
const auth = await authenticateAccessToken(
|
||||
request.headers.authorization,
|
||||
options.authRepository,
|
||||
options.jwtSecret
|
||||
);
|
||||
if (!auth) {
|
||||
reply.status(401).send({
|
||||
code: 'AUTH_SESSION_INVALID', message: 'Authentication required.', traceId: request.traceId
|
||||
});
|
||||
return null;
|
||||
}
|
||||
const access = await options.accessControl.getAccessProfile(
|
||||
auth.session.tenantId,
|
||||
auth.session.user.id
|
||||
);
|
||||
if (!access.capabilities.includes('profile.read')) {
|
||||
reply.status(403).send({
|
||||
code: 'PROFILE_READ_FORBIDDEN', message: 'Profile read permission is required.',
|
||||
traceId: request.traceId
|
||||
});
|
||||
return null;
|
||||
}
|
||||
return { tenantId: auth.session.tenantId, userId: auth.session.user.id };
|
||||
}
|
||||
|
||||
async function requireReader(
|
||||
request: FastifyRequest,
|
||||
reply: FastifyReply,
|
||||
|
||||
Reference in New Issue
Block a user