mirror of
https://github.com/xtr-dev/rondevu-server.git
synced 2025-12-13 20:33:25 +00:00
Refactor getService() method for better maintainability
Break down 138-line method with three helper functions: 1. filterCompatibleServices(): Eliminates duplicate filtering logic - Used in both paginated and random discovery modes - Centralizes version compatibility checking 2. findAvailableOffer(): Encapsulates offer lookup logic - Used across all three modes - Ensures consistent offer selection 3. buildServiceResponse(): Standardizes response formatting - Single source of truth for response structure - Used in all return paths Benefits: - Eliminates 30+ lines of duplicate code - Three modes now clearly separated and documented - Easier to maintain and test each mode independently - Consistent response formatting across all modes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
113
src/rpc.ts
113
src/rpc.ts
@@ -154,7 +154,10 @@ const handlers: Record<string, RpcHandler> = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get service by FQN
|
* Get service by FQN - Supports 3 modes:
|
||||||
|
* 1. Direct lookup: FQN includes @username
|
||||||
|
* 2. Paginated discovery: FQN without @username, with limit/offset
|
||||||
|
* 3. Random discovery: FQN without @username, no limit
|
||||||
*/
|
*/
|
||||||
async getService(params, message, signature, publicKey, storage, config) {
|
async getService(params, message, signature, publicKey, storage, config) {
|
||||||
const { serviceFqn, limit, offset } = params;
|
const { serviceFqn, limit, offset } = params;
|
||||||
@@ -179,50 +182,59 @@ const handlers: Record<string, RpcHandler> = {
|
|||||||
throw new Error('Failed to parse service FQN');
|
throw new Error('Failed to parse service FQN');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paginated discovery mode
|
// Helper: Filter services by version compatibility
|
||||||
if (limit !== undefined) {
|
const filterCompatibleServices = (services) => {
|
||||||
const pageLimit = Math.min(Math.max(1, limit), MAX_PAGE_SIZE);
|
return services.filter((s) => {
|
||||||
const pageOffset = Math.max(0, offset || 0);
|
|
||||||
|
|
||||||
const allServices = await storage.getServicesByName(
|
|
||||||
parsed.service,
|
|
||||||
parsed.version
|
|
||||||
);
|
|
||||||
const compatibleServices = allServices.filter((s) => {
|
|
||||||
const serviceVersion = parseServiceFqn(s.serviceFqn);
|
const serviceVersion = parseServiceFqn(s.serviceFqn);
|
||||||
return (
|
return (
|
||||||
serviceVersion &&
|
serviceVersion &&
|
||||||
isVersionCompatible(parsed.version, serviceVersion.version)
|
isVersionCompatible(parsed.version, serviceVersion.version)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper: Find available offer for service
|
||||||
|
const findAvailableOffer = async (service) => {
|
||||||
|
const offers = await storage.getOffersForService(service.id);
|
||||||
|
return offers.find((o) => !o.answererUsername);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper: Build service response object
|
||||||
|
const buildServiceResponse = (service, offer) => ({
|
||||||
|
serviceId: service.id,
|
||||||
|
username: service.username,
|
||||||
|
serviceFqn: service.serviceFqn,
|
||||||
|
offerId: offer.id,
|
||||||
|
sdp: offer.sdp,
|
||||||
|
createdAt: service.createdAt,
|
||||||
|
expiresAt: service.expiresAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Mode 1: Paginated discovery
|
||||||
|
if (limit !== undefined) {
|
||||||
|
const pageLimit = Math.min(Math.max(1, limit), MAX_PAGE_SIZE);
|
||||||
|
const pageOffset = Math.max(0, offset || 0);
|
||||||
|
|
||||||
|
const allServices = await storage.getServicesByName(parsed.service, parsed.version);
|
||||||
|
const compatibleServices = filterCompatibleServices(allServices);
|
||||||
|
|
||||||
|
// Get unique services per username with available offers
|
||||||
const usernameSet = new Set<string>();
|
const usernameSet = new Set<string>();
|
||||||
const uniqueServices: any[] = [];
|
const uniqueServices: any[] = [];
|
||||||
|
|
||||||
for (const service of compatibleServices) {
|
for (const service of compatibleServices) {
|
||||||
if (!usernameSet.has(service.username)) {
|
if (!usernameSet.has(service.username)) {
|
||||||
usernameSet.add(service.username);
|
usernameSet.add(service.username);
|
||||||
const offers = await storage.getOffersForService(service.id);
|
const availableOffer = await findAvailableOffer(service);
|
||||||
const availableOffer = offers.find((o) => !o.answererUsername);
|
|
||||||
|
|
||||||
if (availableOffer) {
|
if (availableOffer) {
|
||||||
uniqueServices.push({
|
uniqueServices.push(buildServiceResponse(service, availableOffer));
|
||||||
serviceId: service.id,
|
|
||||||
username: service.username,
|
|
||||||
serviceFqn: service.serviceFqn,
|
|
||||||
offerId: availableOffer.id,
|
|
||||||
sdp: availableOffer.sdp,
|
|
||||||
createdAt: service.createdAt,
|
|
||||||
expiresAt: service.expiresAt,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const paginatedServices = uniqueServices.slice(
|
// Paginate results
|
||||||
pageOffset,
|
const paginatedServices = uniqueServices.slice(pageOffset, pageOffset + pageLimit);
|
||||||
pageOffset + pageLimit
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
services: paginatedServices,
|
services: paginatedServices,
|
||||||
@@ -232,68 +244,37 @@ const handlers: Record<string, RpcHandler> = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Direct lookup with username
|
// Mode 2: Direct lookup with username
|
||||||
if (parsed.username) {
|
if (parsed.username) {
|
||||||
const service = await storage.getServiceByFqn(serviceFqn);
|
const service = await storage.getServiceByFqn(serviceFqn);
|
||||||
if (!service) {
|
if (!service) {
|
||||||
throw new Error('Service not found');
|
throw new Error('Service not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
const offers = await storage.getOffersForService(service.id);
|
const availableOffer = await findAvailableOffer(service);
|
||||||
const availableOffer = offers.find((o) => !o.answererUsername);
|
|
||||||
|
|
||||||
if (!availableOffer) {
|
if (!availableOffer) {
|
||||||
throw new Error('Service has no available offers');
|
throw new Error('Service has no available offers');
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return buildServiceResponse(service, availableOffer);
|
||||||
serviceId: service.id,
|
|
||||||
username: service.username,
|
|
||||||
serviceFqn: service.serviceFqn,
|
|
||||||
offerId: availableOffer.id,
|
|
||||||
sdp: availableOffer.sdp,
|
|
||||||
createdAt: service.createdAt,
|
|
||||||
expiresAt: service.expiresAt,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Random discovery without username
|
// Mode 3: Random discovery without username
|
||||||
const allServices = await storage.getServicesByName(
|
const allServices = await storage.getServicesByName(parsed.service, parsed.version);
|
||||||
parsed.service,
|
const compatibleServices = filterCompatibleServices(allServices);
|
||||||
parsed.version
|
|
||||||
);
|
|
||||||
const compatibleServices = allServices.filter((s) => {
|
|
||||||
const serviceVersion = parseServiceFqn(s.serviceFqn);
|
|
||||||
return (
|
|
||||||
serviceVersion &&
|
|
||||||
isVersionCompatible(parsed.version, serviceVersion.version)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (compatibleServices.length === 0) {
|
if (compatibleServices.length === 0) {
|
||||||
throw new Error('No services found');
|
throw new Error('No services found');
|
||||||
}
|
}
|
||||||
|
|
||||||
const randomService =
|
const randomService = compatibleServices[Math.floor(Math.random() * compatibleServices.length)];
|
||||||
compatibleServices[
|
const availableOffer = await findAvailableOffer(randomService);
|
||||||
Math.floor(Math.random() * compatibleServices.length)
|
|
||||||
];
|
|
||||||
const offers = await storage.getOffersForService(randomService.id);
|
|
||||||
const availableOffer = offers.find((o) => !o.answererUsername);
|
|
||||||
|
|
||||||
if (!availableOffer) {
|
if (!availableOffer) {
|
||||||
throw new Error('Service has no available offers');
|
throw new Error('Service has no available offers');
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return buildServiceResponse(randomService, availableOffer);
|
||||||
serviceId: randomService.id,
|
|
||||||
username: randomService.username,
|
|
||||||
serviceFqn: randomService.serviceFqn,
|
|
||||||
offerId: availableOffer.id,
|
|
||||||
sdp: availableOffer.sdp,
|
|
||||||
createdAt: randomService.createdAt,
|
|
||||||
expiresAt: randomService.expiresAt,
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user