Skip to content
This repository was archived by the owner on May 12, 2026. It is now read-only.

Commit 87301c3

Browse files
committed
Method Routings Create
1 parent 8a18b22 commit 87301c3

5 files changed

Lines changed: 295 additions & 15 deletions

File tree

src/routes/(protected)/integration/method-routings/+page.svelte

Lines changed: 96 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@
1212
1313
let methodRoutings = $state<MethodRouting[]>([]);
1414
let methodNames = $state<string[]>([]);
15+
let connectorNames = $state<string[]>([]);
16+
let bankIds = $state<string[]>([]);
1517
let isLoading = $state(false);
1618
let isLoadingMethodNames = $state(false);
19+
let isLoadingConnectors = $state(false);
1720
let error = $state<string | null>(null);
1821
let successMessage = $state<string | null>(null);
1922
let showCreateForm = $state(false);
2023
let editingRouting = $state<MethodRouting | null>(null);
2124
22-
const jsonPlaceholder = '{"key": "value"}';
25+
const jsonPlaceholder = '{"param1": "value1", "param2": "value2"}';
2326
2427
// Form state
2528
let formData = $state<MethodRouting>({
@@ -88,6 +91,53 @@
8891
}
8992
}
9093
94+
async function fetchConnectorNames() {
95+
try {
96+
isLoadingConnectors = true;
97+
98+
const response = await fetch("/api/system/connectors");
99+
100+
if (!response.ok) {
101+
const errorData = await response.json().catch(() => ({}));
102+
const errorMsg = errorData.error || response.statusText;
103+
console.error(`Failed to fetch connectors (${response.status}): ${errorMsg}`);
104+
return;
105+
}
106+
107+
const data = await response.json();
108+
109+
connectorNames = Array.isArray(data)
110+
? data
111+
: data.connector_names || [];
112+
} catch (err) {
113+
console.error("Error fetching connector names:", err);
114+
} finally {
115+
isLoadingConnectors = false;
116+
}
117+
}
118+
119+
async function fetchBankIds() {
120+
try {
121+
const response = await fetch("/api/banks");
122+
123+
if (!response.ok) {
124+
console.error(`Failed to fetch banks (${response.status})`);
125+
return;
126+
}
127+
128+
const data = await response.json();
129+
const banks = Array.isArray(data) ? data : data.banks || [];
130+
131+
// Extract just the bank_id values
132+
bankIds = banks
133+
.map((b: { bank_id?: string }) => b.bank_id)
134+
.filter((id: string | undefined): id is string => !!id)
135+
.sort();
136+
} catch (err) {
137+
console.error("Error fetching bank IDs:", err);
138+
}
139+
}
140+
91141
async function createMethodRouting() {
92142
try {
93143
isLoading = true;
@@ -202,6 +252,8 @@
202252
onMount(() => {
203253
fetchMethodRoutings();
204254
fetchMethodNames();
255+
fetchConnectorNames();
256+
fetchBankIds();
205257
});
206258
</script>
207259

@@ -291,14 +343,30 @@
291343
<label for="connector_name" class="form-label">
292344
Connector Name <span class="required">*</span>
293345
</label>
294-
<input
295-
type="text"
296-
id="connector_name"
297-
bind:value={formData.connector_name}
298-
class="form-input"
299-
placeholder="e.g., rest_vMar2019"
300-
required
301-
/>
346+
{#if isLoadingConnectors}
347+
<div class="loading-text">Loading connectors...</div>
348+
{:else if connectorNames.length > 0}
349+
<select
350+
id="connector_name"
351+
bind:value={formData.connector_name}
352+
class="form-input"
353+
required
354+
>
355+
<option value="">Select a connector</option>
356+
{#each connectorNames as connectorName}
357+
<option value={connectorName}>{connectorName}</option>
358+
{/each}
359+
</select>
360+
{:else}
361+
<input
362+
type="text"
363+
id="connector_name"
364+
bind:value={formData.connector_name}
365+
class="form-input"
366+
placeholder="e.g., rest_vMar2019"
367+
required
368+
/>
369+
{/if}
302370
</div>
303371

304372
<div class="form-group">
@@ -310,8 +378,15 @@
310378
id="bank_id_pattern"
311379
bind:value={formData.bank_id_pattern}
312380
class="form-input"
313-
placeholder="e.g., gh.29.uk or .*"
381+
placeholder="e.g., gh.29.uk or .* for all"
382+
list="bank-ids-list"
314383
/>
384+
<datalist id="bank-ids-list">
385+
{#each bankIds as bankId}
386+
<option value={bankId}></option>
387+
{/each}
388+
</datalist>
389+
<div class="form-hint">Type a bank ID or pattern (e.g., .* for all banks)</div>
315390
</div>
316391

317392
<div class="form-group">
@@ -336,6 +411,7 @@
336411
rows="4"
337412
placeholder={jsonPlaceholder}
338413
></textarea>
414+
<div class="form-hint">Optional key-value pairs as JSON object, e.g., {"{"}"key1": "value1", "key2": "value2"{"}"}</div>
339415
</div>
340416
</div>
341417

@@ -562,6 +638,16 @@
562638
color: var(--color-surface-400);
563639
}
564640
641+
.form-hint {
642+
font-size: 0.75rem;
643+
color: #6b7280;
644+
margin-top: 0.25rem;
645+
}
646+
647+
:global([data-mode="dark"]) .form-hint {
648+
color: var(--color-surface-400);
649+
}
650+
565651
.form-actions {
566652
display: flex;
567653
justify-content: flex-end;

src/routes/api/devops/connector-method-names/+server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const GET: RequestHandler = async ({ locals }) => {
2727

2828
try {
2929
logger.info("=== CONNECTOR METHOD NAMES API CALL ===");
30-
const endpoint = `/obp/v6.0.0/devops/connector-method-names`;
30+
const endpoint = `/obp/v6.0.0/system/connector-method-names`;
3131
logger.info(`Request: ${endpoint}`);
3232

3333
const response = await obp_requests.get(endpoint, accessToken);
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { json } from "@sveltejs/kit";
2+
import type { RequestHandler } from "./$types";
3+
import { obp_requests } from "$lib/obp/requests";
4+
import { extractErrorDetails } from "$lib/obp/errors";
5+
import { SessionOAuthHelper } from "$lib/oauth/sessionHelper";
6+
import { createLogger } from "$lib/utils/logger";
7+
8+
const logger = createLogger("ConnectorMethodsAPI");
9+
10+
// GET - Fetch all connector methods
11+
export const GET: RequestHandler = async ({ locals }) => {
12+
const session = locals.session;
13+
14+
if (!session?.data?.user) {
15+
logger.error("No user in session - returning 401");
16+
return json(
17+
{ error: "Unauthorized - No user in session" },
18+
{ status: 401 },
19+
);
20+
}
21+
22+
const sessionOAuth = SessionOAuthHelper.getSessionOAuth(session);
23+
const accessToken = sessionOAuth?.accessToken;
24+
25+
if (!accessToken) {
26+
logger.error("No access token available for connector methods API call");
27+
return json({ error: "No API access token available" }, { status: 401 });
28+
}
29+
30+
try {
31+
logger.info("=== CONNECTOR METHODS API CALL ===");
32+
const endpoint = `/obp/v6.0.0/management/connector-methods`;
33+
logger.info(`Request: ${endpoint}`);
34+
35+
const response = await obp_requests.get(endpoint, accessToken);
36+
37+
logger.info("Connector methods fetched successfully");
38+
logger.info(`Response: ${response?.connectors_methods?.length || 0} connector methods`);
39+
40+
return json(response.connectors_methods || []);
41+
} catch (err) {
42+
logger.error("ERROR FETCHING CONNECTOR METHODS:", err);
43+
44+
// Extract full error details - NEVER hide or simplify OBP error messages!
45+
const { message, obpErrorCode } = extractErrorDetails(err);
46+
47+
return json(
48+
{
49+
error: message,
50+
obpErrorCode,
51+
},
52+
{ status: 500 },
53+
);
54+
}
55+
};

src/routes/api/integration/method-routings/+server.ts

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,59 @@ export const GET: RequestHandler = async ({ locals }) => {
7272
}
7373
};
7474

75+
// Helper to transform parameters from form input to OBP format
76+
// OBP expects: parameters: [{key: "k1", value: "v1"}, {key: "k2", value: "v2"}]
77+
function transformParameters(params: unknown): Array<{key: string, value: string}> {
78+
// If empty or null, return empty array
79+
if (!params || params === "") {
80+
return [];
81+
}
82+
83+
// If already an array, return as-is
84+
if (Array.isArray(params)) {
85+
return params;
86+
}
87+
88+
// If it's a string, try to parse it as JSON
89+
if (typeof params === "string") {
90+
const trimmed = params.trim();
91+
if (!trimmed) {
92+
return [];
93+
}
94+
95+
try {
96+
const parsed = JSON.parse(trimmed);
97+
98+
// If parsed result is an array, return it
99+
if (Array.isArray(parsed)) {
100+
return parsed;
101+
}
102+
103+
// If parsed result is an object like {"key1": "value1", "key2": "value2"},
104+
// convert to [{key: "key1", value: "value1"}, {key: "key2", value: "value2"}]
105+
if (typeof parsed === "object" && parsed !== null) {
106+
return Object.entries(parsed).map(([key, value]) => ({
107+
key,
108+
value: String(value),
109+
}));
110+
}
111+
} catch {
112+
logger.warn(`Failed to parse parameters as JSON: ${trimmed}`);
113+
return [];
114+
}
115+
}
116+
117+
// If it's an object (but not array), convert entries
118+
if (typeof params === "object" && params !== null) {
119+
return Object.entries(params).map(([key, value]) => ({
120+
key,
121+
value: String(value),
122+
}));
123+
}
124+
125+
return [];
126+
}
127+
75128
// POST - Create a new method routing
76129
export const POST: RequestHandler = async ({ request, locals }) => {
77130
const session = locals.session;
@@ -96,12 +149,23 @@ export const POST: RequestHandler = async ({ request, locals }) => {
96149

97150
try {
98151
const body = await request.json();
99-
logger.info("Creating method routing with data:", body);
152+
logger.info("Creating method routing with raw data:", body);
153+
154+
// Transform the body for OBP API
155+
const obpBody = {
156+
method_name: body.method_name,
157+
connector_name: body.connector_name,
158+
is_bank_id_exact_match: body.is_bank_id_exact_match ?? false,
159+
bank_id_pattern: body.bank_id_pattern || "",
160+
parameters: transformParameters(body.parameters),
161+
};
162+
163+
logger.info("Transformed body for OBP:", obpBody);
100164

101165
const endpoint = `/obp/v3.1.0/management/method_routings`;
102166
logger.info(`Request: POST ${endpoint}`);
103167

104-
const response = await obp_requests.post(endpoint, body, accessToken);
168+
const response = await obp_requests.post(endpoint, obpBody, accessToken);
105169

106170
logger.info("Method routing created successfully");
107171
logger.debug(JSON.stringify(response, null, 2));
@@ -159,12 +223,23 @@ export const PUT: RequestHandler = async ({ request, locals }) => {
159223
);
160224
}
161225

162-
logger.info(`Updating method routing ${methodRoutingId} with data:`, body);
226+
logger.info(`Updating method routing ${methodRoutingId} with raw data:`, body);
227+
228+
// Transform the body for OBP API
229+
const obpBody = {
230+
method_name: body.method_name,
231+
connector_name: body.connector_name,
232+
is_bank_id_exact_match: body.is_bank_id_exact_match ?? false,
233+
bank_id_pattern: body.bank_id_pattern || "",
234+
parameters: transformParameters(body.parameters),
235+
};
236+
237+
logger.info("Transformed body for OBP:", obpBody);
163238

164239
const endpoint = `/obp/v3.1.0/management/method_routings/${methodRoutingId}`;
165240
logger.info(`Request: PUT ${endpoint}`);
166241

167-
const response = await obp_requests.put(endpoint, body, accessToken);
242+
const response = await obp_requests.put(endpoint, obpBody, accessToken);
168243

169244
logger.info("Method routing updated successfully");
170245
logger.debug(JSON.stringify(response, null, 2));

0 commit comments

Comments
 (0)