feat(M08-A): 接入顾客端个人中心

This commit is contained in:
Codex
2026-06-25 11:43:25 +08:00
parent c7c869c18b
commit 7446852cca
14 changed files with 476 additions and 4 deletions
+32 -1
View File
@@ -18,7 +18,7 @@ const listSchema = z.object({
});
export interface MemberRouteOptions {
service: Pick<MemberProfileService, 'listMembers' | 'getMember'>;
service: Pick<MemberProfileService, 'listMembers' | 'getMember' | 'getMyProfile'>;
authRepository: Pick<AuthRepository, 'validateSession'>;
accessControl: { getAccessProfile(tenantId: string, userId: string): Promise<AccessProfile> };
jwtSecret: string;
@@ -28,6 +28,37 @@ export async function registerMemberRoutes(
app: FastifyInstance,
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
});
}
return handle(reply, request.traceId, async () => ({
code: 0,
data: await options.service.getMyProfile({
tenantId: auth.session.tenantId,
userId: auth.session.user.id
}),
traceId: request.traceId
}));
});
app.get('/admin-api/members', async (request, reply) => {
const actor = await requireReader(request, reply, options);
if (!actor) return;