|
@@ -118,7 +118,13 @@ export class ShopsEndpoint extends BaseEndpointComponent {
|
|
|
name: 'limit',
|
|
name: 'limit',
|
|
|
in: 'query',
|
|
in: 'query',
|
|
|
type: 'number',
|
|
type: 'number',
|
|
|
- description: 'Maximum number of results to return'
|
|
|
|
|
|
|
+ description: 'Maximum number of results to return (default: 50)'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ name: 'offset',
|
|
|
|
|
+ in: 'query',
|
|
|
|
|
+ type: 'number',
|
|
|
|
|
+ description: 'Number of results to skip for pagination (default: 0)'
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
|
name: 'date_from',
|
|
name: 'date_from',
|
|
@@ -563,20 +569,22 @@ export class ShopsEndpoint extends BaseEndpointComponent {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Parse query parameters
|
|
// Parse query parameters
|
|
|
- const limit = req.query.limit ? parseInt(req.query.limit as string) : undefined;
|
|
|
|
|
|
|
+ const limit = req.query.limit ? parseInt(req.query.limit as string) : 50; // Default to 50
|
|
|
|
|
+ const offset = req.query.offset ? parseInt(req.query.offset as string) : 0;
|
|
|
const dateFrom = req.query.date_from as string | undefined;
|
|
const dateFrom = req.query.date_from as string | undefined;
|
|
|
const dateTo = req.query.date_to as string | undefined;
|
|
const dateTo = req.query.date_to as string | undefined;
|
|
|
const contentType = req.query.content_type as string | undefined;
|
|
const contentType = req.query.content_type as string | undefined;
|
|
|
|
|
|
|
|
- // Get content with filters
|
|
|
|
|
|
|
+ // Get content with filters (now returns only latest versions)
|
|
|
const allContent = this.db.getAllContent(shop.id, {
|
|
const allContent = this.db.getAllContent(shop.id, {
|
|
|
limit,
|
|
limit,
|
|
|
|
|
+ offset,
|
|
|
dateFrom,
|
|
dateFrom,
|
|
|
dateTo,
|
|
dateTo,
|
|
|
contentType
|
|
contentType
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- // Group by type and URL (latest version of each URL)
|
|
|
|
|
|
|
+ // Group by type in a single pass - O(n) instead of O(n²)
|
|
|
const grouped: { [key: string]: any[] } = {
|
|
const grouped: { [key: string]: any[] } = {
|
|
|
shipping_informations: [],
|
|
shipping_informations: [],
|
|
|
contacts: [],
|
|
contacts: [],
|
|
@@ -584,45 +592,40 @@ export class ShopsEndpoint extends BaseEndpointComponent {
|
|
|
faq: []
|
|
faq: []
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- const urlMap = new Map<string, any>();
|
|
|
|
|
for (const content of allContent) {
|
|
for (const content of allContent) {
|
|
|
- const key = `${content.content_type}:${content.url}`;
|
|
|
|
|
- if (!urlMap.has(key)) {
|
|
|
|
|
- urlMap.set(key, {
|
|
|
|
|
- url: content.url,
|
|
|
|
|
- content: content.content,
|
|
|
|
|
- changed: Boolean(content.changed),
|
|
|
|
|
- last_updated: content.updated_at
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Organize by type
|
|
|
|
|
- for (const content of allContent) {
|
|
|
|
|
- const key = `${content.content_type}:${content.url}`;
|
|
|
|
|
- const urlKey = urlMap.get(key);
|
|
|
|
|
-
|
|
|
|
|
- if (!urlKey) continue;
|
|
|
|
|
-
|
|
|
|
|
const typeKey = content.content_type === 'shipping' ? 'shipping_informations' :
|
|
const typeKey = content.content_type === 'shipping' ? 'shipping_informations' :
|
|
|
content.content_type === 'contacts' ? 'contacts' :
|
|
content.content_type === 'contacts' ? 'contacts' :
|
|
|
content.content_type === 'terms' ? 'terms_of_conditions' :
|
|
content.content_type === 'terms' ? 'terms_of_conditions' :
|
|
|
'faq';
|
|
'faq';
|
|
|
|
|
|
|
|
- // Only add if not already added
|
|
|
|
|
- if (!grouped[typeKey].find((c: any) => c.url === urlKey.url)) {
|
|
|
|
|
- grouped[typeKey].push(urlKey);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ grouped[typeKey].push({
|
|
|
|
|
+ url: content.url,
|
|
|
|
|
+ content: content.content,
|
|
|
|
|
+ changed: Boolean(content.changed),
|
|
|
|
|
+ last_updated: content.updated_at,
|
|
|
|
|
+ title: content.title
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // Count total items for pagination
|
|
|
|
|
+ const totalItems = allContent.length;
|
|
|
|
|
+ const hasMore = totalItems === limit;
|
|
|
|
|
+
|
|
|
res.json({
|
|
res.json({
|
|
|
shop_id: shop.id,
|
|
shop_id: shop.id,
|
|
|
filters: {
|
|
filters: {
|
|
|
- limit: limit || null,
|
|
|
|
|
|
|
+ limit,
|
|
|
|
|
+ offset,
|
|
|
date_from: dateFrom || null,
|
|
date_from: dateFrom || null,
|
|
|
date_to: dateTo || null,
|
|
date_to: dateTo || null,
|
|
|
content_type: contentType || null
|
|
content_type: contentType || null
|
|
|
},
|
|
},
|
|
|
|
|
+ pagination: {
|
|
|
|
|
+ total_returned: totalItems,
|
|
|
|
|
+ limit,
|
|
|
|
|
+ offset,
|
|
|
|
|
+ has_more: hasMore
|
|
|
|
|
+ },
|
|
|
results: grouped
|
|
results: grouped
|
|
|
});
|
|
});
|
|
|
} catch (error) {
|
|
} catch (error) {
|