EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
route.ts
Go to the documentation of this file.
1/**
2 * Example API Route Using Session Context
3 *
4 * This demonstrates the proper pattern for creating API routes that:
5 * 1. Check authentication from session
6 * 2. Route to correct store URL based on session
7 * 3. Handle different request types (openapi, gnap, elink)
8 * 4. Enforce security: Retail stores can ONLY use ELINK
9 */
10
11import { NextRequest, NextResponse } from "next/server";
12import { getRequestContext, validateStoreAccess, getStoreApiUrl, validateApiAccess } from "@/lib/server/sessionUtils";
13import { FieldpineServerApi } from "@/lib/server/fieldpineApi";
14
15/**
16 * GET /api/v1/example-session
17 * Example endpoint demonstrating session-based routing with security
18 */
19export async function GET(request: NextRequest) {
20 try {
21 // 1. Get session and store context
22 const context = await getRequestContext(request);
23
24 if (!context) {
25 return NextResponse.json(
26 { success: false, error: "Unauthorized - Please log in" },
27 { status: 401 }
28 );
29 }
30
31 // 2. SECURITY: Validate API access based on store type
32 // Retail stores can ONLY use ELINK, management portal can use all
33 const apiAccessValidation = validateApiAccess(context, 'elink');
34 if (!apiAccessValidation.valid) {
35 console.warn(`[API Security] Access denied: ${apiAccessValidation.error}`);
36 return NextResponse.json(
37 {
38 success: false,
39 error: apiAccessValidation.error,
40 code: apiAccessValidation.errorCode
41 },
42 { status: 403 }
43 );
44 }
45
46 // 3. Validate store type if needed (optional)
47 // For example, if this endpoint only works in retail stores:
48 const validation = validateStoreAccess(context, 'store');
49 if (!validation.valid) {
50 return NextResponse.json(
51 { success: false, error: validation.error },
52 { status: 403 }
53 );
54 }
55
56 // 4. Get the appropriate API URL for the request type
57 // Retail stores: ONLY 'elink' is allowed
58 // Management portal: Can use 'openapi', 'gnap', or 'elink'
59 const apiUrl = getStoreApiUrl(context, 'elink');
60
61 // 5. Create Fieldpine API client with store-specific URL
62 const api = new FieldpineServerApi(apiUrl);
63
64 // 6. Make API calls using the session's API key
65 // Example ELINK call
66 const buckParams = {
67 "3": "retailmax.elink.products",
68 "9": "f501,0,test",
69 "99": Math.random().toString()
70 };
71 const response = await api.buckApiCall(buckParams, context.session.apiKey);
72
73 // 7. Return the data
74 return NextResponse.json({
75 success: true,
76 data: response,
77 meta: {
78 store: context.store.name,
79 storeType: context.store.type,
80 apiUrl: apiUrl,
81 user: context.session.username,
82 allowedEndpoints: context.isRetailStore ? ['ELINK only'] : ['OpenAPI', 'GNAP', 'ELINK']
83 }
84 });
85
86 } catch (error: any) {
87 console.error("[Example Session API] Error:", error);
88 return NextResponse.json(
89 { success: false, error: error.message || "Internal server error" },
90 { status: 500 }
91 );
92 }
93}
94
95/**
96 * Example demonstrating management portal access to GNAP
97 * This will be BLOCKED for retail stores
98 */
99export async function POST(request: NextRequest) {
100 try {
101 const context = await getRequestContext(request);
102
103 if (!context) {
104 return NextResponse.json(
105 { success: false, error: "Unauthorized" },
106 { status: 401 }
107 );
108 }
109
110 // SECURITY: Validate GNAP access (retail stores will be BLOCKED)
111 const apiAccessValidation = validateApiAccess(context, 'gnap');
112 if (!apiAccessValidation.valid) {
113 console.warn(`[API Security] GNAP access denied for retail store: ${context.store.name}`);
114 return NextResponse.json(
115 {
116 success: false,
117 error: apiAccessValidation.error,
118 code: apiAccessValidation.errorCode,
119 hint: 'GNAP endpoints are restricted to management portal only'
120 },
121 { status: 403 }
122 );
123 }
124
125 // GNAP requests always go to IIG management portal
126 const gnapUrl = getStoreApiUrl(context, 'gnap');
127 const api = new FieldpineServerApi(gnapUrl);
128
129 // Example BUCK call for reports
130 const buckParams = {
131 "3": "retailmax.report.sales",
132 "9": "f110,4,today",
133 "99": Math.random().toString()
134 };
135
136 const response = await api.buckApiCall(buckParams, context.session.apiKey);
137
138 return NextResponse.json({
139 success: true,
140 data: response,
141 meta: {
142 requestType: 'gnap',
143 apiUrl: gnapUrl,
144 store: context.store.name,
145 note: 'This endpoint is only accessible from management portal'
146 }
147 });
148
149 } catch (error: any) {
150 console.error("[Example GNAP API] Error:", error);
151 return NextResponse.json(
152 { success: false, error: error.message },
153 { status: 500 }
154 );
155 }
156}