-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Expand file tree
/
Copy pathroute.ts
More file actions
131 lines (108 loc) · 3.65 KB
/
Copy pathroute.ts
File metadata and controls
131 lines (108 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import { NextResponse } from "next/server"
import { IS_PROD } from "@/lib/utils/env"
import type { ABTestConfig, MatomoExperiment } from "@/lib/ab-testing/types"
export const revalidate = 3600
const isExperimentActive = (experiment: MatomoExperiment): boolean => {
const now = new Date()
// Check start date - if scheduled for future, not active yet
if (experiment.start_date) {
const startDate = new Date(experiment.start_date)
if (now < startDate) return false
}
// Check end date - if past end date, not active anymore
if (experiment.end_date) {
const endDate = new Date(experiment.end_date)
if (now > endDate) return false
}
// If no scheduling constraints, enabled if created or running
return ["created", "running"].includes(experiment.status)
}
const getPreviewConfig = () => ({
AppTest: {
id: "preview",
enabled: true,
variants: [{ name: "Original", weight: 100 }],
},
})
export async function GET() {
// Preview mode: Show menu with original default
if (!IS_PROD) {
return NextResponse.json(getPreviewConfig())
}
try {
const matomoUrl = process.env.NEXT_PUBLIC_MATOMO_URL
const apiToken = process.env.MATOMO_API_TOKEN
if (!matomoUrl || !apiToken) {
return NextResponse.json(
{ error: "Matomo configuration missing" },
{ status: 500 }
)
}
const siteId = process.env.NEXT_PUBLIC_MATOMO_SITE_ID || "4"
// Add cache busting for development
const cacheBuster =
process.env.NODE_ENV === "development" ? `&cb=${Date.now()}` : ""
const matomoApiUrl = `${matomoUrl}/index.php?module=API&method=AbTesting.getAllExperiments&idSite=${siteId}&format=json&token_auth=${apiToken}${cacheBuster}`
const response = await fetch(matomoApiUrl, {
next: { revalidate: process.env.NODE_ENV === "development" ? 0 : 3600 },
headers: { "User-Agent": "ethereum.org-ab-testing/1.0" },
})
const data = await response.json()
if (data.result === "error" || !Array.isArray(data)) {
console.error(
"[AB Config] Matomo API error:",
data.message || "Invalid response"
)
return NextResponse.json(
{},
{
headers: {
"Cache-Control": "s-max-age=300, stale-while-revalidate=600",
},
}
)
}
const experiments: MatomoExperiment[] = data
// Transform Matomo experiments to our config format
const config: Record<string, ABTestConfig> = {}
experiments
.filter((exp) => exp.variations && exp.variations.length > 0)
.forEach((exp) => {
// Calculate Original variant weight (100% - sum of all variations)
const variationsTotalWeight = exp.variations.reduce(
(sum, variation) => sum + (variation.percentage || 0),
0
)
const originalWeight = 100 - variationsTotalWeight
// Build variants array starting with "Original"
const variants = [
{ name: "Original", weight: originalWeight },
...exp.variations.map((variation) => ({
name: variation.name,
weight: variation.percentage || 0,
})),
]
config[exp.name] = {
name: exp.name,
id: exp.idexperiment,
enabled: isExperimentActive(exp),
variants,
}
})
return NextResponse.json(config, {
headers: {
"Cache-Control": "s-max-age=3600, stale-while-revalidate=7200",
},
})
} catch (error) {
console.error("[AB Config] Failed to fetch AB test configuration:", error)
return NextResponse.json(
{},
{
headers: {
"Cache-Control": "no-cache",
},
}
)
}
}