wip
This commit is contained in:
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@@ -0,0 +1,2 @@
|
||||
.git
|
||||
Dockerfile
|
||||
21
app/api/email-template-test/route.ts
Normal file
21
app/api/email-template-test/route.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { sendEmail } from "~/lib/services/mailer.service";
|
||||
|
||||
export const GET = async () => {
|
||||
const { renderInviteEmail } = await import('@kit/email-templates');
|
||||
|
||||
const html = await renderInviteEmail({
|
||||
language: 'en',
|
||||
teamName: 'Test Team',
|
||||
invitedUserEmail: 'test@example.com',
|
||||
productName: 'Test Product',
|
||||
teamLogo: 'https://placehold.co/100x100',
|
||||
inviter: 'John Doe',
|
||||
link: 'https://www.google.com',
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
html,
|
||||
length: html.html.length,
|
||||
});
|
||||
};
|
||||
@@ -2,10 +2,10 @@ import axios from 'axios';
|
||||
import { XMLParser } from 'fast-xml-parser';
|
||||
import fs from 'fs';
|
||||
import { createAnalysisGroup, getAnalysisGroups } from '~/lib/services/analysis-group.service';
|
||||
import { IMedipostPublicMessageDataParsed } from '~/lib/services/medipost.types';
|
||||
import { IMedipostPublicMessageDataParsed, IUuringElement } from '~/lib/services/medipost.types';
|
||||
import { createAnalysis, createNoDataReceivedEntry, createNoNewDataReceivedEntry, createSyncFailEntry, createSyncSuccessEntry } from '~/lib/services/analyses.service';
|
||||
import { getLastCheckedDate } from '~/lib/services/sync-entries.service';
|
||||
import { createAnalysisElement } from '~/lib/services/analysis-element.service';
|
||||
import { createAnalysisElement, getAnalysisElements } from '~/lib/services/analysis-element.service';
|
||||
import { createCodes } from '~/lib/services/codes.service';
|
||||
import { getLatestPublicMessageListItem } from '~/lib/services/medipost.service';
|
||||
import type { ICode } from '~/lib/types/code';
|
||||
@@ -80,81 +80,92 @@ export default async function syncAnalysisGroups() {
|
||||
}
|
||||
|
||||
const codes: ICode[] = [];
|
||||
const analysesToCreate: { analysisGroupId: number, analyses: IUuringElement[], analysisElementId: number }[] = [];
|
||||
for (const analysisGroup of analysisGroups) {
|
||||
let analysisGroupId: number | undefined;
|
||||
const existingAnalysisGroup = existingAnalysisGroups?.find(({ original_id }) => original_id === analysisGroup.UuringuGruppId);
|
||||
if (existingAnalysisGroup) {
|
||||
console.info(`Analysis group '${analysisGroup.UuringuGruppNimi}' already exists`);
|
||||
continue;
|
||||
analysisGroupId = existingAnalysisGroup.id;
|
||||
} else {
|
||||
// SAVE ANALYSIS GROUP
|
||||
analysisGroupId = await createAnalysisGroup({
|
||||
id: analysisGroup.UuringuGruppId,
|
||||
name: analysisGroup.UuringuGruppNimi,
|
||||
order: analysisGroup.UuringuGruppJarjekord,
|
||||
});
|
||||
|
||||
const analysisGroupCodes = toArray(analysisGroup.Kood);
|
||||
codes.push(
|
||||
...analysisGroupCodes.map((kood) => ({
|
||||
hk_code: kood.HkKood,
|
||||
hk_code_multiplier: kood.HkKoodiKordaja,
|
||||
coefficient: kood.Koefitsient,
|
||||
price: kood.Hind,
|
||||
analysis_group_id: analysisGroupId!,
|
||||
analysis_element_id: null,
|
||||
analysis_id: null,
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
||||
// SAVE ANALYSIS GROUP
|
||||
const analysisGroupId = await createAnalysisGroup({
|
||||
id: analysisGroup.UuringuGruppId,
|
||||
name: analysisGroup.UuringuGruppNimi,
|
||||
order: analysisGroup.UuringuGruppJarjekord,
|
||||
});
|
||||
|
||||
const analysisGroupCodes = toArray(analysisGroup.Kood);
|
||||
codes.push(
|
||||
...analysisGroupCodes.map((kood) => ({
|
||||
hk_code: kood.HkKood,
|
||||
hk_code_multiplier: kood.HkKoodiKordaja,
|
||||
coefficient: kood.Koefitsient,
|
||||
price: kood.Hind,
|
||||
analysis_group_id: analysisGroupId,
|
||||
analysis_element_id: null,
|
||||
analysis_id: null,
|
||||
})),
|
||||
);
|
||||
|
||||
const analysisGroupItems = toArray(analysisGroup.Uuring);
|
||||
|
||||
for (const item of analysisGroupItems) {
|
||||
const analysisElement = item.UuringuElement;
|
||||
|
||||
const insertedAnalysisElementId = await createAnalysisElement({
|
||||
analysisElement,
|
||||
analysisGroupId,
|
||||
materialGroups: toArray(item.MaterjalideGrupp),
|
||||
});
|
||||
let insertedAnalysisElementId: number | undefined;
|
||||
const existingAnalysisElement = (await getAnalysisElements({ originalIds: [analysisElement.UuringId] }))?.[0];
|
||||
if (existingAnalysisElement) {
|
||||
console.info(`Analysis element '${analysisElement.UuringNimi}' already exists`);
|
||||
insertedAnalysisElementId = existingAnalysisElement.id;
|
||||
} else {
|
||||
insertedAnalysisElementId = await createAnalysisElement({
|
||||
analysisElement,
|
||||
analysisGroupId: analysisGroupId!,
|
||||
materialGroups: toArray(item.MaterjalideGrupp),
|
||||
});
|
||||
if (analysisElement.Kood) {
|
||||
const analysisElementCodes = toArray(analysisElement.Kood);
|
||||
codes.push(
|
||||
...analysisElementCodes.map((kood) => ({
|
||||
hk_code: kood.HkKood,
|
||||
hk_code_multiplier: kood.HkKoodiKordaja,
|
||||
coefficient: kood.Koefitsient,
|
||||
price: kood.Hind,
|
||||
analysis_group_id: null,
|
||||
analysis_element_id: insertedAnalysisElementId!,
|
||||
analysis_id: null,
|
||||
})),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const analyses = toArray(analysisElement.UuringuElement);
|
||||
if (analyses?.length && insertedAnalysisElementId) {
|
||||
analysesToCreate.push({ analysisGroupId: analysisGroupId!, analyses, analysisElementId: insertedAnalysisElementId });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const { analysisGroupId, analyses, analysisElementId } of analysesToCreate) {
|
||||
for (const analysis of analyses) {
|
||||
const insertedAnalysisId = await createAnalysis(analysis, analysisElementId);
|
||||
if (analysis.Kood) {
|
||||
const analysisCodes = toArray(analysis.Kood);
|
||||
|
||||
if (analysisElement.Kood) {
|
||||
const analysisElementCodes = toArray(analysisElement.Kood);
|
||||
codes.push(
|
||||
...analysisElementCodes.map((kood) => ({
|
||||
...analysisCodes.map((kood) => ({
|
||||
hk_code: kood.HkKood,
|
||||
hk_code_multiplier: kood.HkKoodiKordaja,
|
||||
coefficient: kood.Koefitsient,
|
||||
price: kood.Hind,
|
||||
analysis_group_id: null,
|
||||
analysis_element_id: insertedAnalysisElementId,
|
||||
analysis_id: null,
|
||||
analysis_element_id: null,
|
||||
analysis_id: insertedAnalysisId,
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
||||
const analyses = analysisElement.UuringuElement;
|
||||
if (analyses?.length) {
|
||||
for (const analysis of analyses) {
|
||||
const insertedAnalysisId = await createAnalysis(analysis, analysisGroupId);
|
||||
|
||||
if (analysis.Kood) {
|
||||
const analysisCodes = toArray(analysis.Kood);
|
||||
|
||||
codes.push(
|
||||
...analysisCodes.map((kood) => ({
|
||||
hk_code: kood.HkKood,
|
||||
hk_code_multiplier: kood.HkKoodiKordaja,
|
||||
coefficient: kood.Koefitsient,
|
||||
price: kood.Hind,
|
||||
analysis_group_id: null,
|
||||
analysis_element_id: null,
|
||||
analysis_id: insertedAnalysisId,
|
||||
})),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ export const POST = async (request: NextRequest) => {
|
||||
console.error("Error syncing analysis groups", e);
|
||||
return NextResponse.json({
|
||||
message: 'Failed to sync analysis groups',
|
||||
error: e instanceof Error ? JSON.stringify(e, undefined, 2) : 'Unknown error',
|
||||
}, { status: 500 });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Link from 'next/link';
|
||||
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
import { SignInMethodsContainer } from '@kit/auth/sign-in';
|
||||
import { authConfig, pathsConfig } from '@kit/shared/config';
|
||||
@@ -9,6 +9,7 @@ import { Trans } from '@kit/ui/trans';
|
||||
|
||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||
import { getSupabaseServerClient } from '@/packages/supabase/src/clients/server-client';
|
||||
|
||||
interface SignInPageProps {
|
||||
searchParams: Promise<{
|
||||
@@ -40,6 +41,21 @@ async function SignInPage({ searchParams }: SignInPageProps) {
|
||||
updateAccount: pathsConfig.auth.updateAccount,
|
||||
};
|
||||
|
||||
// const { data, error } = await getSupabaseServerClient()
|
||||
// .auth
|
||||
// .signInWithOAuth({
|
||||
// provider: 'keycloak',
|
||||
// });
|
||||
|
||||
// if (error) {
|
||||
// console.error('OAuth error', error);
|
||||
// redirect('/');
|
||||
// }
|
||||
|
||||
// if (data.url) {
|
||||
// redirect(data.url);
|
||||
// }
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={'flex flex-col items-center gap-1'}>
|
||||
|
||||
@@ -17,6 +17,7 @@ import { formatCurrency } from "@/packages/shared/src/utils";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { handleNavigateToPayment } from "@/lib/services/medusaCart.service";
|
||||
import AnalysisLocation from "./analysis-location";
|
||||
import { composeOrderXML, getOrderedAnalysisIds } from "~/lib/services/medipost.service";
|
||||
|
||||
const IS_DISCOUNT_SHOWN = false as boolean;
|
||||
|
||||
@@ -133,6 +134,26 @@ export default function Cart({
|
||||
<Trans i18nKey="cart:checkout.goToCheckout" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Button type='button' onClick={async () => {
|
||||
const orderedAnalysisElementsIds = await getOrderedAnalysisIds({ medusaOrder: { items: cart.items ?? [] } });
|
||||
const xml = await composeOrderXML({
|
||||
person: {
|
||||
idCode: '1234567890',
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
phone: '1234567890',
|
||||
},
|
||||
orderedAnalysisElementsIds: orderedAnalysisElementsIds.map(({ analysisElementId }) => analysisElementId).filter(Boolean) as number[],
|
||||
orderedAnalysesIds: orderedAnalysisElementsIds.map(({ analysisId }) => analysisId).filter(Boolean) as number[],
|
||||
orderId: '1234567890',
|
||||
orderCreatedAt: new Date(),
|
||||
});
|
||||
console.log('test', { items: cart.items, ids: orderedAnalysisElementsIds, xml });
|
||||
console.log('test', xml);
|
||||
}}>
|
||||
Test
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ export default function OrderAnalysesCards({
|
||||
className="px-2 text-black"
|
||||
onClick={() => handleSelect(variant.id)}
|
||||
>
|
||||
{variantAddingToCart ? <Loader2 className="size-4 stroke-2 animate-spin" /> : <ShoppingCart className="size-4 stroke-2" />}
|
||||
{variantAddingToCart === variant.id ? <Loader2 className="size-4 stroke-2 animate-spin" /> : <ShoppingCart className="size-4 stroke-2" />}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
8362
current-test-data.sql
Normal file
8362
current-test-data.sql
Normal file
File diff suppressed because one or more lines are too long
@@ -2,7 +2,7 @@ import type { Tables } from '@/packages/supabase/src/database.types';
|
||||
import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client';
|
||||
import type { IUuringElement } from "./medipost.types";
|
||||
|
||||
type AnalysesWithGroupsAndElements = ({
|
||||
export type AnalysesWithGroupsAndElements = ({
|
||||
analysis_elements: Tables<{ schema: 'medreport' }, 'analysis_elements'> & {
|
||||
analysis_groups: Tables<{ schema: 'medreport' }, 'analysis_groups'>;
|
||||
};
|
||||
|
||||
@@ -37,10 +37,10 @@ import { Tables } from '@kit/supabase/database';
|
||||
import { createAnalysisGroup } from './analysis-group.service';
|
||||
import { getSupabaseServerAdminClient } from '@/packages/supabase/src/clients/server-admin-client';
|
||||
import { getOrder, updateOrderStatus } from './order.service';
|
||||
import { getAnalysisElements, getAnalysisElementsAdmin } from './analysis-element.service';
|
||||
import { getAnalyses } from './analyses.service';
|
||||
import { AnalysisElement, getAnalysisElements, getAnalysisElementsAdmin } from './analysis-element.service';
|
||||
import { AnalysesWithGroupsAndElements, getAnalyses } from './analyses.service';
|
||||
import { getAccountAdmin } from './account.service';
|
||||
import { StoreOrder } from '@medusajs/types';
|
||||
import { StoreOrder, StoreOrderLineItem } from '@medusajs/types';
|
||||
import { listProducts } from '@lib/data/products';
|
||||
import { listRegions } from '@lib/data/regions';
|
||||
import { getAnalysisElementMedusaProductIds } from '@/utils/medusa-product';
|
||||
@@ -480,72 +480,60 @@ export async function composeOrderXML({
|
||||
throw new Error(`Got ${analyses.length} analyses, expected ${orderedAnalysesIds.length}`);
|
||||
}
|
||||
|
||||
const uniques = [
|
||||
...analysisElements?.flatMap(({ analysis_groups }) => analysis_groups) ?? [],
|
||||
...analyses?.flatMap(({ analysis_elements }) => analysis_elements.analysis_groups) ?? []
|
||||
];
|
||||
const analysisGroups: Tables<{ schema: 'medreport' }, 'analysis_groups'>[] =
|
||||
uniqBy(
|
||||
(
|
||||
analysisElements?.flatMap(({ analysis_groups }) => analysis_groups) ??
|
||||
[]
|
||||
).concat(
|
||||
analyses?.flatMap(
|
||||
({ analysis_elements }) => analysis_elements.analysis_groups,
|
||||
) ?? [],
|
||||
),
|
||||
'id',
|
||||
);
|
||||
uniqBy(uniques, 'id');
|
||||
console.log('analysisGroups', { analysisGroups, uniques });
|
||||
|
||||
const specimenSection = [];
|
||||
const analysisSection = [];
|
||||
let order = 1;
|
||||
for (const currentGroup of analysisGroups) {
|
||||
let relatedAnalysisElement = analysisElements?.find(
|
||||
(element) => element.analysis_groups.id === currentGroup.id,
|
||||
);
|
||||
const relatedAnalyses = analyses?.filter((analysis) => {
|
||||
return analysis.analysis_elements.analysis_groups.id === currentGroup.id;
|
||||
const relatedAnalysisElements = await getRelatedAnalysisElements({
|
||||
analysisElements,
|
||||
analyses,
|
||||
currentGroup,
|
||||
});
|
||||
|
||||
if (!relatedAnalysisElement) {
|
||||
relatedAnalysisElement = relatedAnalyses?.find(
|
||||
(relatedAnalysis) =>
|
||||
relatedAnalysis.analysis_elements.analysis_groups.id ===
|
||||
currentGroup.id,
|
||||
)?.analysis_elements;
|
||||
}
|
||||
for (const relatedAnalysisElement of relatedAnalysisElements) {
|
||||
if (!relatedAnalysisElement || !relatedAnalysisElement.material_groups) {
|
||||
throw new Error(
|
||||
`Failed to find related analysis element for group ${currentGroup.name} (id: ${currentGroup.id})`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!relatedAnalysisElement || !relatedAnalysisElement.material_groups) {
|
||||
throw new Error(
|
||||
`Failed to find related analysis element for group ${currentGroup.name} (id: ${currentGroup.id})`,
|
||||
for (const group of relatedAnalysisElement?.material_groups as MaterjalideGrupp[]) {
|
||||
const materials = toArray(group.Materjal);
|
||||
const specimenXml = materials.flatMap(
|
||||
({ MaterjaliNimi, MaterjaliTyyp, MaterjaliTyypOID, Konteiner }) => {
|
||||
return toArray(Konteiner).map((container) =>
|
||||
getSpecimen(
|
||||
MaterjaliTyypOID,
|
||||
MaterjaliTyyp,
|
||||
MaterjaliNimi,
|
||||
order,
|
||||
container.ProovinouKoodOID,
|
||||
container.ProovinouKood,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
specimenSection.push(...specimenXml);
|
||||
}
|
||||
|
||||
const groupXml = getAnalysisGroup(
|
||||
currentGroup.original_id,
|
||||
currentGroup.name,
|
||||
order,
|
||||
relatedAnalysisElement,
|
||||
);
|
||||
order++;
|
||||
analysisSection.push(groupXml);
|
||||
}
|
||||
|
||||
for (const group of relatedAnalysisElement?.material_groups as MaterjalideGrupp[]) {
|
||||
const materials = toArray(group.Materjal);
|
||||
const specimenXml = materials.flatMap(
|
||||
({ MaterjaliNimi, MaterjaliTyyp, MaterjaliTyypOID, Konteiner }) => {
|
||||
return toArray(Konteiner).map((container) =>
|
||||
getSpecimen(
|
||||
MaterjaliTyypOID,
|
||||
MaterjaliTyyp,
|
||||
MaterjaliNimi,
|
||||
order,
|
||||
container.ProovinouKoodOID,
|
||||
container.ProovinouKood,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
specimenSection.push(...specimenXml);
|
||||
}
|
||||
|
||||
const groupXml = getAnalysisGroup(
|
||||
currentGroup.original_id,
|
||||
currentGroup.name,
|
||||
order,
|
||||
relatedAnalysisElement,
|
||||
);
|
||||
order++;
|
||||
analysisSection.push(groupXml);
|
||||
}
|
||||
|
||||
return `<?xml version="1.0" encoding="UTF-8"?>
|
||||
@@ -695,7 +683,7 @@ async function syncPrivateMessage({
|
||||
);
|
||||
}
|
||||
|
||||
const { data: allOrderResponseElements} = await supabase
|
||||
const { data: allOrderResponseElements } = await supabase
|
||||
.schema('medreport')
|
||||
.from('analysis_response_elements')
|
||||
.select('*')
|
||||
@@ -784,10 +772,13 @@ export async function sendOrderToMedipost({
|
||||
await updateOrderStatus({ medusaOrderId, orderStatus: 'PROCESSING' });
|
||||
}
|
||||
|
||||
type OrderItems = {
|
||||
items: Pick<StoreOrderLineItem, 'product'>[];
|
||||
}
|
||||
export async function getOrderedAnalysisIds({
|
||||
medusaOrder,
|
||||
}: {
|
||||
medusaOrder: StoreOrder;
|
||||
medusaOrder: OrderItems;
|
||||
}): Promise<{
|
||||
analysisElementId?: number;
|
||||
analysisId?: number;
|
||||
@@ -795,7 +786,7 @@ export async function getOrderedAnalysisIds({
|
||||
const countryCodes = await listRegions();
|
||||
const countryCode = countryCodes[0]!.countries![0]!.iso_2!;
|
||||
|
||||
async function getOrderedAnalysisElements(medusaOrder: StoreOrder) {
|
||||
async function getOrderedAnalysisElements(medusaOrder: OrderItems) {
|
||||
const originalIds = (medusaOrder?.items ?? [])
|
||||
.map((a) => a.product?.metadata?.analysisIdOriginal)
|
||||
.filter((a) => typeof a === 'string') as string[];
|
||||
@@ -803,7 +794,7 @@ export async function getOrderedAnalysisIds({
|
||||
return analysisElements.map(({ id }) => ({ analysisElementId: id }));
|
||||
}
|
||||
|
||||
async function getOrderedAnalyses(medusaOrder: StoreOrder) {
|
||||
async function getOrderedAnalyses(medusaOrder: OrderItems) {
|
||||
const originalIds = (medusaOrder?.items ?? [])
|
||||
.map((a) => a.product?.metadata?.analysisIdOriginal)
|
||||
.filter((a) => typeof a === 'string') as string[];
|
||||
@@ -811,7 +802,7 @@ export async function getOrderedAnalysisIds({
|
||||
return analyses.map(({ id }) => ({ analysisId: id }));
|
||||
}
|
||||
|
||||
async function getOrderedAnalysisPackages(medusaOrder: StoreOrder) {
|
||||
async function getOrderedAnalysisPackages(medusaOrder: OrderItems) {
|
||||
const orderedPackages = (medusaOrder?.items ?? []).filter(({ product }) => product?.handle.startsWith(ANALYSIS_PACKAGE_HANDLE_PREFIX));
|
||||
const orderedPackageIds = orderedPackages.map(({ product }) => product?.id).filter(Boolean) as string[];
|
||||
if (orderedPackageIds.length === 0) {
|
||||
@@ -868,10 +859,10 @@ export async function createMedipostActionLog({
|
||||
hasError = false,
|
||||
}: {
|
||||
action:
|
||||
| 'send_order_to_medipost'
|
||||
| 'sync_analysis_results_from_medipost'
|
||||
| 'send_fake_analysis_results_to_medipost'
|
||||
| 'send_analysis_results_to_medipost';
|
||||
| 'send_order_to_medipost'
|
||||
| 'sync_analysis_results_from_medipost'
|
||||
| 'send_fake_analysis_results_to_medipost'
|
||||
| 'send_analysis_results_to_medipost';
|
||||
xml: string;
|
||||
hasAnalysisResults?: boolean;
|
||||
medusaOrderId?: string | null;
|
||||
@@ -892,3 +883,39 @@ export async function createMedipostActionLog({
|
||||
.select('id')
|
||||
.throwOnError();
|
||||
}
|
||||
|
||||
async function getRelatedAnalysisElements({
|
||||
analysisElements,
|
||||
analyses,
|
||||
currentGroup,
|
||||
}: {
|
||||
analysisElements: AnalysisElement[];
|
||||
analyses: AnalysesWithGroupsAndElements;
|
||||
currentGroup: {
|
||||
created_at: string;
|
||||
id: number;
|
||||
name: string;
|
||||
order: number;
|
||||
original_id: string;
|
||||
updated_at: string | null;
|
||||
};
|
||||
}) {
|
||||
const relatedAnalysisElements: AnalysisElement[] = [];
|
||||
|
||||
const related1 = analysisElements?.filter(
|
||||
(element) => element.analysis_groups.id === currentGroup.id,
|
||||
);
|
||||
if (related1) {
|
||||
relatedAnalysisElements.push(...related1);
|
||||
}
|
||||
|
||||
const related2 = analyses
|
||||
?.filter(({ analysis_elements }) => analysis_elements.analysis_groups.id === currentGroup.id)
|
||||
?.filter(({ analysis_elements }) => analysis_elements.analysis_groups.id === currentGroup.id)
|
||||
?.flatMap(({ analysis_elements }) => analysis_elements);
|
||||
if (related2) {
|
||||
relatedAnalysisElements.push(...related2);
|
||||
}
|
||||
|
||||
return relatedAnalysisElements;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ export async function handleNavigateToPayment({
|
||||
const paymentLink =
|
||||
await new MontonioOrderHandlerService().getMontonioPaymentLink({
|
||||
notificationUrl: `${env().medusaBackendPublicUrl}/hooks/payment/montonio_montonio`,
|
||||
returnUrl: `${env().siteUrl}/home/cart/montonio-callback`,
|
||||
returnUrl: `${"https://webhook.site"}/home/cart/montonio-callback`,
|
||||
amount: cart.total,
|
||||
currency: cart.currency_code.toUpperCase(),
|
||||
description: `Order from Medreport`,
|
||||
|
||||
5
local-sync/listofproductids.js
Normal file
5
local-sync/listofproductids.js
Normal file
@@ -0,0 +1,5 @@
|
||||
const list = ["prod_01K2JQF451ZKVV97FMX10T6DG1","prod_01K2JQFECMKR1CGDYQV81HB2W1","prod_01K2JQCZKZRZWD71CRN84V84NJ","prod_01K2JQD1AWQH7VHGPS4BA4028A","prod_01K2JQD321BMZTP7R4ZXEJNR17","prod_01K2JQD4RCRGERJRY8JQB7VWMT","prod_01K2JQD6F2VDANADSB5HY6WB6M","prod_01K2JQD85JGDRE0EJSQXGB74SE","prod_01K2JQD9VG391PZ02ZS57Y72PC","prod_01K2JQDBHYMESBB332PHF5TNTB", "prod_01K2JQG1EK4VTFH4GR2ZVB1RK6", "prod_01K2JQH0AMN407P1234MJ64BZM"]
|
||||
|
||||
const list2 = ['prod_01K2JQF451ZKVV97FMX10T6DG1', 'prod_01K2JQFECMKR1CGDYQV81HB2W1', 'prod_01K2JQCZKZRZWD71CRN84V84NJ', 'prod_01K2JQD1AWQH7VHGPS4BA4028A', 'prod_01K2JQD321BMZTP7R4ZXEJNR17', 'prod_01K2JQD4RCRGERJRY8JQB7VWMT', 'prod_01K2JQD6F2VDANADSB5HY6WB6M', 'prod_01K2JQD85JGDRE0EJSQXGB74SE', 'prod_01K2JQD9VG391PZ02ZS57Y72PC', 'prod_01K2JQDBHYMESBB332PHF5TNTB', 'prod_01K2JQG1EK4VTFH4GR2ZVB1RK6', 'prod_01K2JQH0AMN407P1234MJ64BZM']
|
||||
|
||||
console.log(list2.map(a => `'${a}'`).join(', '));
|
||||
8
local-sync/local-order.http
Normal file
8
local-sync/local-order.http
Normal file
@@ -0,0 +1,8 @@
|
||||
function send_medipost_test_response() {
|
||||
curl -X POST "$HOSTNAME/api/order/medipost-test-response" \
|
||||
--header "x-jobs-api-key: $JOBS_API_TOKEN" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{ "medusaOrderId": "'$MEDUSA_ORDER_ID'" }'
|
||||
}
|
||||
|
||||
#
|
||||
16
local-sync/syncinbrowser.js
Normal file
16
local-sync/syncinbrowser.js
Normal file
@@ -0,0 +1,16 @@
|
||||
const SyncHelper = {
|
||||
async send() {
|
||||
await fetch('https://test.medreport.ee/api/order/medipost-test-response', {
|
||||
method: "POST",
|
||||
headers: { "x-jobs-api-key": "fd26ec26-70ed-11f0-9e95-431ac3b15a84", "content-type": "application/json" },
|
||||
body: JSON.stringify({ "medusaOrderId": "order_01K2F3KC87NTMZX04T3KDZAQ69" }),
|
||||
});
|
||||
},
|
||||
async sync() {
|
||||
await fetch('https://test.medreport.ee/api/job/sync-analysis-results', {
|
||||
method: "POST",
|
||||
headers: { "x-jobs-api-key": "fd26ec26-70ed-11f0-9e95-431ac3b15a84" },
|
||||
});
|
||||
},
|
||||
};
|
||||
SyncHelper.sync()
|
||||
157
local-sync/test-cron-setup.md
Normal file
157
local-sync/test-cron-setup.md
Normal file
@@ -0,0 +1,157 @@
|
||||
# Testing the Supabase Cron Job Setup
|
||||
|
||||
This guide provides step-by-step instructions to test your Supabase cron job configuration.
|
||||
|
||||
## Quick Setup Commands
|
||||
|
||||
### 1. Deploy the Migration (Option A)
|
||||
|
||||
If you want to use the migration approach:
|
||||
|
||||
```bash
|
||||
# Make sure you're connected to your Supabase project
|
||||
npm run supabase:deploy
|
||||
```
|
||||
|
||||
Then manually update the migration file with your actual values before deploying.
|
||||
|
||||
### 2. Manual Setup (Option B - Recommended)
|
||||
|
||||
Use the SQL Editor in Supabase Dashboard:
|
||||
|
||||
1. Go to your Supabase Dashboard → Database → SQL Editor
|
||||
2. Copy and paste the content from `supabase/sql/setup-cron-job.sql`
|
||||
3. Run the SQL to create the function
|
||||
4. Then execute the schedule function with your actual values:
|
||||
|
||||
```sql
|
||||
select schedule_sync_analysis_results_cron(
|
||||
'https://your-production-domain.com', -- Your actual API URL
|
||||
'your-actual-jobs-api-token' -- Your actual JOBS_API_TOKEN
|
||||
);
|
||||
```
|
||||
|
||||
## Testing Steps
|
||||
|
||||
### 1. Verify Extensions are Enabled
|
||||
|
||||
```sql
|
||||
select * from pg_extension where extname in ('pg_cron', 'pg_net');
|
||||
```
|
||||
|
||||
Expected result: Both `pg_cron` and `pg_net` should be listed.
|
||||
|
||||
### 2. Check Job is Scheduled
|
||||
|
||||
```sql
|
||||
select * from cron.job where jobname = 'sync-analysis-results-every-15-minutes';
|
||||
```
|
||||
|
||||
Expected result: One row with your job details, `active` should be `true`.
|
||||
|
||||
### 3. Test API Endpoint Manually
|
||||
|
||||
Before relying on the cron job, test your API endpoint manually:
|
||||
|
||||
```bash
|
||||
curl -X POST https://your-domain.com/api/job/sync-analysis-results \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "x-jobs-api-key: YOUR_JOBS_API_TOKEN" \
|
||||
-v
|
||||
```
|
||||
|
||||
Expected result: Status 200 with success message.
|
||||
|
||||
### 4. Monitor Job Execution
|
||||
|
||||
Wait for the job to run (up to 15 minutes), then check execution history:
|
||||
|
||||
```sql
|
||||
select
|
||||
job_run_details.*,
|
||||
job.jobname
|
||||
from cron.job_run_details
|
||||
join cron.job on job.jobid = job_run_details.jobid
|
||||
where job.jobname = 'sync-analysis-results-every-15-minutes'
|
||||
order by start_time desc
|
||||
limit 5;
|
||||
```
|
||||
|
||||
### 5. Check Application Logs
|
||||
|
||||
Monitor your application logs to see if the API calls are being received and processed successfully.
|
||||
|
||||
## Environment Variables Required
|
||||
|
||||
Make sure these environment variables are set in your production environment:
|
||||
|
||||
- `JOBS_API_TOKEN` - The API key for authenticating job requests
|
||||
- All other environment variables required by your `sync-analysis-results` handler
|
||||
|
||||
## Common Issues and Solutions
|
||||
|
||||
### Issue 1: Job Not Appearing
|
||||
|
||||
**Problem**: Job doesn't appear in `cron.job` table.
|
||||
|
||||
**Solution**:
|
||||
- Check if you have sufficient permissions
|
||||
- Ensure extensions are enabled
|
||||
- Try running the schedule function again
|
||||
|
||||
### Issue 2: Job Scheduled but Not Running
|
||||
|
||||
**Problem**: Job appears in table but no execution history.
|
||||
|
||||
**Solutions**:
|
||||
- Check if `active` is `true` in `cron.job` table
|
||||
- Verify cron schedule format is correct
|
||||
- Check Supabase logs for any cron-related errors
|
||||
|
||||
### Issue 3: HTTP Requests Failing
|
||||
|
||||
**Problem**: Job runs but API calls fail.
|
||||
|
||||
**Solutions**:
|
||||
- Test API endpoint manually with curl
|
||||
- Verify API URL is correct and accessible from Supabase
|
||||
- Check if `JOBS_API_TOKEN` is correct
|
||||
- Ensure your application is deployed and running
|
||||
|
||||
### Issue 4: Authentication Errors
|
||||
|
||||
**Problem**: Getting 401 Unauthorized responses.
|
||||
|
||||
**Solutions**:
|
||||
- Verify `x-jobs-api-key` header is included
|
||||
- Check that `JOBS_API_TOKEN` matches between cron job and application
|
||||
- Ensure the header name is exactly `x-jobs-api-key` (case-sensitive)
|
||||
|
||||
## Cleanup Commands
|
||||
|
||||
If you need to remove the cron job:
|
||||
|
||||
```sql
|
||||
-- Unschedule the job
|
||||
select cron.unschedule('sync-analysis-results-every-15-minutes');
|
||||
|
||||
-- Drop the helper function (optional)
|
||||
drop function if exists schedule_sync_analysis_results_cron(text, text);
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
Once the cron job is working:
|
||||
|
||||
1. Remove any old instrumentation.ts cron logic if it exists
|
||||
2. Monitor the job performance and adjust interval if needed
|
||||
3. Set up alerting for failed job executions
|
||||
4. Consider adding more detailed logging to your API endpoint
|
||||
|
||||
## Support
|
||||
|
||||
If you encounter issues:
|
||||
|
||||
1. Check the troubleshooting section in `docs/supabase-cron-setup.md`
|
||||
2. Review Supabase documentation for pg_cron and pg_net
|
||||
3. Contact your team for deployment-specific configuration details
|
||||
1090
local-sync/xmls/SendPrivateMessageToTervise_cURL.sh
Executable file
1090
local-sync/xmls/SendPrivateMessageToTervise_cURL.sh
Executable file
File diff suppressed because it is too large
Load Diff
138
local-sync/xmls/curl2.sh
Executable file
138
local-sync/xmls/curl2.sh
Executable file
@@ -0,0 +1,138 @@
|
||||
curl --location 'https://meditest.medisoft.ee:7443/Medipost/MedipostServlet' \
|
||||
--form 'Action="SendPrivateMessage";type=text/plain; charset=UTF-8' \
|
||||
--form 'User="trvurgtst";type=text/plain; charset=UTF-8' \
|
||||
--form 'Password="SRB48HZMV";type=text/plain; charset=UTF-8' \
|
||||
--form 'Receiver="trvurgtst";type=text/plain; charset=UTF-8' \
|
||||
--form 'MessageType="Tellimus";type=text/plain; charset=UTF-8' \
|
||||
--form 'Message="<?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
||||
<Saadetis xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"TellimusLOINC.xsd\">
|
||||
<Pais>
|
||||
<Pakett versioon=\"20\">OL</Pakett>
|
||||
<Saatja>trvurgtst</Saatja>
|
||||
<Saaja>trvurgtst</Saaja>
|
||||
<Aeg>2022-07-22 11:31:57</Aeg>
|
||||
<SaadetisId>234254234</SaadetisId>
|
||||
<Email>info@terviseuuringud.ee</Email>
|
||||
</Pais>
|
||||
|
||||
<Tellimus cito=\"EI\">
|
||||
<ValisTellimuseId>1288</ValisTellimuseId>
|
||||
|
||||
<\!--<TellijaAsutus>-->
|
||||
<Asutus tyyp=\"TELLIJA\">
|
||||
<AsutuseId>12702440</AsutuseId>
|
||||
<AsutuseNimi>Health Tests OÜ</AsutuseNimi>
|
||||
<AsutuseKood>TSU</AsutuseKood>
|
||||
<AllyksuseNimi/>
|
||||
<Telefon>+37256257117</Telefon>
|
||||
<Vald>0387</Vald>
|
||||
<Aadress>Valukoja 10, 11415 Tallinn</Aadress>
|
||||
</Asutus>
|
||||
|
||||
<\!--<TeostajaAsutus>-->
|
||||
<Asutus tyyp=\"TEOSTAJA\">
|
||||
<AsutuseId>12702440</AsutuseId>
|
||||
<AsutuseNimi>Health Tests OÜ</AsutuseNimi>
|
||||
<AsutuseKood>TSU</AsutuseKood>
|
||||
<AllyksuseNimi/>
|
||||
<Telefon>+37256257117</Telefon>
|
||||
<Vald>0387</Vald>
|
||||
<Aadress>Valukoja 10, 11415 Tallinn</Aadress>
|
||||
</Asutus>
|
||||
|
||||
<\!--<TellijaIsik>-->
|
||||
<Personal tyyp=\"TELLIJA\">
|
||||
<\!--Tervishoiutöötaja kood (OID: 1.3.6.1.4.1.28284.6.2.4.9)
|
||||
või Eesti isikukood (OID: 1.3.6.1.4.1.28284.6.2.2.1) -->
|
||||
<PersonalOID>1.3.6.1.4.1.28284.6.2.2.1</PersonalOID>
|
||||
<PersonalKood>D07907</PersonalKood>
|
||||
<PersonalPerekonnaNimi>Tsvetkov</PersonalPerekonnaNimi>
|
||||
<PersonalEesNimi>Eduard</PersonalEesNimi>
|
||||
<Telefon>+3725555000</Telefon>
|
||||
</Personal>
|
||||
|
||||
|
||||
<\!--<SisestajaIsik>-->
|
||||
<Personal tyyp=\"SISESTAJA\">
|
||||
<\!--Tervishoiutöötaja kood (OID: 1.3.6.1.4.1.28284.6.2.4.9)
|
||||
või Eesti isikukood (OID: 1.3.6.1.4.1.28284.6.2.2.1) -->
|
||||
<PersonalOID>1.3.6.1.4.1.28284.6.2.2.1</PersonalOID>
|
||||
<PersonalKood>D07907</PersonalKood>
|
||||
<PersonalPerekonnaNimi>Tsvetkov</PersonalPerekonnaNimi>
|
||||
<PersonalEesNimi>Eduard</PersonalEesNimi>
|
||||
</Personal>
|
||||
|
||||
|
||||
<TellijaMarkused>Siia tuleb tellija poolne märkus</TellijaMarkused>
|
||||
|
||||
<Patsient>
|
||||
<IsikukoodiOID>1.3.6.1.4.1.28284.6.2.2.1</IsikukoodiOID>
|
||||
<Isikukood>37907262736</Isikukood>
|
||||
<PerekonnaNimi>KIVIRÜÜT</PerekonnaNimi>
|
||||
<EesNimi>ARGO</EesNimi>
|
||||
<SynniAeg>1979-07-26</SynniAeg>
|
||||
<SuguOID>1.3.6.1.4.1.28284.6.2.3.16.2</SuguOID>
|
||||
<Sugu>M</Sugu>
|
||||
</Patsient>
|
||||
|
||||
<Konfidentsiaalsus>
|
||||
<PatsiendileOID>2.16.840.1.113883.5.25</PatsiendileOID>
|
||||
<Patsiendile>N</Patsiendile>
|
||||
<ArstileOID>1.3.6.1.4.1.28284.6.2.2.39.1</ArstileOID>
|
||||
<Arstile>N</Arstile>
|
||||
<EsindajaleOID>1.3.6.1.4.1.28284.6.2.2.37.1</EsindajaleOID>
|
||||
<Esindajale>N</Esindajale>
|
||||
</Konfidentsiaalsus>
|
||||
<Proov>
|
||||
<ProovinouIdOID>1.3.6.1.4.1.28284.6.2.4.100</ProovinouIdOID>
|
||||
<ProovinouId>ANI7570-16522287</ProovinouId>
|
||||
<MaterjaliTyypOID>1.3.6.1.4.1.28284.6.2.1.244.8</MaterjaliTyypOID>
|
||||
<MaterjaliTyyp>119297000</MaterjaliTyyp>
|
||||
<MaterjaliNimi>Veri</MaterjaliNimi>
|
||||
<Ribakood>16522287</Ribakood>
|
||||
<Jarjenumber>7570</Jarjenumber>
|
||||
<VotmisAeg>2022-06-13 08:53:00</VotmisAeg>
|
||||
</Proov>
|
||||
<Proov>
|
||||
<ProovinouIdOID>1.3.6.1.4.1.28284.6.2.4.100</ProovinouIdOID>
|
||||
<ProovinouId>ANI7571-16522288</ProovinouId>
|
||||
<MaterjaliTyypOID>1.3.6.1.4.1.28284.6.2.1.244.8</MaterjaliTyypOID>
|
||||
<MaterjaliTyyp>119297000</MaterjaliTyyp>
|
||||
<MaterjaliNimi>Veri</MaterjaliNimi>
|
||||
<Ribakood>16522288</Ribakood>
|
||||
<Jarjenumber>7571</Jarjenumber>
|
||||
<VotmisAeg>2022-06-13 08:53:00</VotmisAeg>
|
||||
</Proov>
|
||||
<UuringuGrupp>
|
||||
<UuringuGruppId>TL10</UuringuGruppId>
|
||||
<UuringuGruppNimi>Hematoloogilised uuringud</UuringuGruppNimi>
|
||||
<Uuring>
|
||||
<UuringuElement>
|
||||
<UuringIdOID>2.16.840.1.113883.6.1</UuringIdOID>
|
||||
<UuringId>57021-8</UuringId>
|
||||
<TLyhend>B-CBC-5Diff</TLyhend>
|
||||
<KNimetus>Hemogramm 5-osalise leukogrammiga</KNimetus>
|
||||
<UuringNimi>Hemogramm</UuringNimi>
|
||||
<TellijaUuringId>18327</TellijaUuringId>
|
||||
</UuringuElement>
|
||||
<ProoviJarjenumber>7570</ProoviJarjenumber>
|
||||
</Uuring>
|
||||
</UuringuGrupp>
|
||||
<UuringuGrupp>
|
||||
<UuringuGruppId>TL40</UuringuGruppId>
|
||||
<UuringuGruppNimi>Kliinilise keemia uuringud</UuringuGruppNimi>
|
||||
<Uuring>
|
||||
<UuringuElement>
|
||||
<UuringIdOID>2.16.840.1.113883.6.1</UuringIdOID>
|
||||
<UuringId>L-3757</UuringId>
|
||||
<TLyhend>B-HbA1c panel</TLyhend>
|
||||
<KNimetus>HbA1c paneel</KNimetus>
|
||||
<UuringNimi>HbA1c</UuringNimi>
|
||||
<TellijaUuringId>18349</TellijaUuringId>
|
||||
</UuringuElement>
|
||||
<ProoviJarjenumber>7571</ProoviJarjenumber>
|
||||
</Uuring>
|
||||
</UuringuGrupp>
|
||||
</Tellimus>
|
||||
</Saadetis>
|
||||
";type=text/xml; charset=UTF-8'
|
||||
98
local-sync/xmls/order6.xml
Normal file
98
local-sync/xmls/order6.xml
Normal file
@@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<Saadetis xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="TellimusLOINC.xsd">
|
||||
<Pais>
|
||||
<Pakett versioon="20">OL</Pakett>
|
||||
|
||||
<Saatja>trvurgtst</Saatja>
|
||||
<Saaja>trvurgtst</Saaja>
|
||||
<Aeg>2025-08-04 03:30:15</Aeg>
|
||||
<SaadetisId>
|
||||
1</SaadetisId>
|
||||
<Email>argo@medreport.ee</Email>
|
||||
</Pais>
|
||||
<Tellimus cito="EI">
|
||||
<ValisTellimuseId>
|
||||
1</ValisTellimuseId>
|
||||
<!--<TellijaAsutus>-->
|
||||
<Asutus tyyp="TELLIJA">
|
||||
<AsutuseId>16381793</AsutuseId>
|
||||
<AsutuseNimi>MedReport
|
||||
OÜ</AsutuseNimi>
|
||||
<AsutuseKood>TSU</AsutuseKood>
|
||||
<Telefon>+37258871517</Telefon>
|
||||
</Asutus>
|
||||
|
||||
<!--<TeostajaAsutus>-->
|
||||
<Asutus tyyp="TEOSTAJA">
|
||||
<AsutuseId>11107913</AsutuseId>
|
||||
<AsutuseNimi>Synlab HTI
|
||||
Tallinn</AsutuseNimi>
|
||||
<AsutuseKood>SLA</AsutuseKood>
|
||||
<AllyksuseNimi>Synlab HTI Tallinn</AllyksuseNimi>
|
||||
|
||||
<Telefon>+3723417123</Telefon>
|
||||
</Asutus>
|
||||
<!--<TellijaIsik>-->
|
||||
<Personal tyyp="TELLIJA"
|
||||
jarjenumber="1">
|
||||
<PersonalOID>1.3.6.1.4.1.28284.6.2.4.9</PersonalOID>
|
||||
<PersonalKood>
|
||||
39610230904</PersonalKood>
|
||||
<PersonalPerekonnaNimi>test2</PersonalPerekonnaNimi>
|
||||
<PersonalEesNimi>
|
||||
test1</PersonalEesNimi>
|
||||
<Telefon>56232775</Telefon>
|
||||
</Personal>
|
||||
<TellijaMarkused>Test
|
||||
comment</TellijaMarkused>
|
||||
<Patsient>
|
||||
<IsikukoodiOID>1.3.6.1.4.1.28284.6.2.2.1</IsikukoodiOID>
|
||||
|
||||
<Isikukood>39610230904</Isikukood>
|
||||
<PerekonnaNimi>test2</PerekonnaNimi>
|
||||
<EesNimi>
|
||||
test1</EesNimi>
|
||||
<SynniAeg>1996-00-23</SynniAeg>
|
||||
<SuguOID>1.3.6.1.4.1.28284.6.2.3.16.2</SuguOID>
|
||||
|
||||
<Sugu>male</Sugu>
|
||||
</Patsient>
|
||||
<Konfidentsiaalsus>
|
||||
<PatsiendileOID>
|
||||
2.16.840.1.113883.5.25</PatsiendileOID>
|
||||
<Patsiendile>N</Patsiendile>
|
||||
<ArstileOID>
|
||||
1.3.6.1.4.1.28284.6.2.2.39.1</ArstileOID>
|
||||
<Arstile>N</Arstile>
|
||||
<EsindajaleOID>
|
||||
1.3.6.1.4.1.28284.6.2.2.37.1</EsindajaleOID>
|
||||
<Esindajale>N</Esindajale>
|
||||
</Konfidentsiaalsus>
|
||||
|
||||
<Proov>
|
||||
<ProovinouIdOID>1.3.6.1.4.1.28284.6.2.1.243.16</ProovinouIdOID>
|
||||
<ProovinouId>A2</ProovinouId>
|
||||
<MaterjaliTyypOID>1.3.6.1.4.1.28284.6.2.1.244.10</MaterjaliTyypOID>
|
||||
<MaterjaliTyyp>119364003</MaterjaliTyyp>
|
||||
<MaterjaliNimi>Seerum</MaterjaliNimi>
|
||||
<Jarjenumber>1</Jarjenumber>
|
||||
</Proov>
|
||||
<UuringuGrupp>
|
||||
<UuringuGruppId>TL106</UuringuGruppId>
|
||||
<UuringuGruppNimi>Söömishäirete uuringud</UuringuGruppNimi>
|
||||
<Uuring>
|
||||
<UuringuElement>
|
||||
<UuringIdOID>2.16.840.1.113883.6.1</UuringIdOID>
|
||||
<UuringId>2276-4</UuringId>
|
||||
<TLyhend>S,P-Fer</TLyhend>
|
||||
<KNimetus>Ferritiin</KNimetus>
|
||||
<UuringNimi>Ferritiin</UuringNimi>
|
||||
<TellijaUuringId>84</TellijaUuringId>
|
||||
</UuringuElement>
|
||||
<ProoviJarjenumber>1</ProoviJarjenumber>
|
||||
</Uuring>
|
||||
</UuringuGrupp>
|
||||
</Tellimus>
|
||||
</Saadetis>
|
||||
76
local-sync/xmls/order9.xml
Normal file
76
local-sync/xmls/order9.xml
Normal file
@@ -0,0 +1,76 @@
|
||||
<?xml version= \"1.0\" encoding= \"UTF-8\"?>
|
||||
<Saadetis xmlns:xsi= \"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation= \"TellimusLOINC.xsd\">
|
||||
<Pais>
|
||||
<Pakett versioon= \"20\">OL</Pakett>
|
||||
<Saatja>trvurgtst</Saatja>
|
||||
<Saaja>trvurgtst</Saaja>
|
||||
<Aeg>2025-08-04 06:22:18</Aeg>
|
||||
<SaadetisId>TSU000001200</SaadetisId>
|
||||
<Email>argo@medreport.ee</Email>
|
||||
</Pais>
|
||||
<Vastus>
|
||||
<ValisTellimuseId>TSU000001200</ValisTellimuseId>
|
||||
<Asutus tyyp= \"TELLIJA\" jarjenumber= \"1\">
|
||||
<AsutuseId>16381793</AsutuseId>
|
||||
<AsutuseNimi>MedReport OÜ</AsutuseNimi>
|
||||
<AsutuseKood>TSU</AsutuseKood>
|
||||
<Telefon>+37258871517</Telefon>
|
||||
</Asutus>
|
||||
<Asutus tyyp= \"TEOSTAJA\" jarjenumber= \"1\">
|
||||
<AsutuseId>11107913</AsutuseId>
|
||||
<AsutuseNimi>Synlab HTI Tallinn</AsutuseNimi>
|
||||
<AsutuseKood>SLA</AsutuseKood>
|
||||
<AllyksuseNimi>Synlab HTI Tallinn</AllyksuseNimi>
|
||||
<Telefon>+3723417123</Telefon>
|
||||
</Asutus>
|
||||
<Personal tyyp= \"TELLIJA\" jarjenumber= \"1\">
|
||||
<PersonalOID>1.3.6.1.4.1.28284.6.2.4.9</PersonalOID>
|
||||
<PersonalKood>39610230903</PersonalKood>
|
||||
<PersonalPerekonnaNimi>User</PersonalPerekonnaNimi>
|
||||
<PersonalEesNimi>Test</PersonalEesNimi>
|
||||
<Telefon>+37256232775</Telefon>
|
||||
</Personal>
|
||||
<TellijaMarkused>Siia tuleb tellija poolne märkus</TellijaMarkused>
|
||||
|
||||
<TellimuseNumber>TSU000001200</TellimuseNumber>
|
||||
<TellimuseOlek>4</TellimuseOlek>
|
||||
<Patsient>
|
||||
<IsikukoodiOID>1.3.6.1.4.1.28284.6.2.2.1</IsikukoodiOID>
|
||||
<Isikukood>39610230903</Isikukood>
|
||||
<PerekonnaNimi>User</PerekonnaNimi>
|
||||
<EesNimi>Test</EesNimi>
|
||||
<SynniAeg>1996-00-23</SynniAeg>
|
||||
<SuguOID>1.3.6.1.4.1.28284.6.2.3.16.2</SuguOID>
|
||||
<Sugu>male</Sugu>
|
||||
</Patsient>
|
||||
|
||||
|
||||
<UuringuGrupp>
|
||||
<UuringuGruppId>TL106</UuringuGruppId>
|
||||
<UuringuGruppNimi>Söömishäirete uuringud</UuringuGruppNimi>
|
||||
<Uuring>
|
||||
<UuringuElement>
|
||||
<UuringIdOID>2.16.840.1.113883.6.1</UuringIdOID>
|
||||
<UuringId>2276-4</UuringId>
|
||||
<TLyhend>S,P-Fer</TLyhend>
|
||||
<KNimetus>Ferritiin</KNimetus>
|
||||
<UuringNimi>Ferritiin</UuringNimi>
|
||||
<TellijaUuringId>84</TellijaUuringId>
|
||||
<TeostajaUuringId>84</TeostajaUuringId>
|
||||
<UuringOlek>4</UuringOlek>
|
||||
<Mootyhik>%</Mootyhik>
|
||||
<UuringuVastus>
|
||||
<VastuseVaartus>30000</VastuseVaartus>
|
||||
<VastuseAeg>2025-08-04 07:00:12</VastuseAeg>
|
||||
<NormYlem kaasaarvatud= \"EI\">100000</NormYlem>
|
||||
<NormAlum kaasaarvatud= \"EI\">50</NormAlum>
|
||||
<NormiStaatus>0</NormiStaatus>
|
||||
<ProoviJarjenumber>1</ProoviJarjenumber>
|
||||
</UuringuVastus>
|
||||
</UuringuElement>
|
||||
<UuringuTaitjaAsutuseJnr>2</UuringuTaitjaAsutuseJnr>
|
||||
</Uuring>
|
||||
</UuringuGrupp>
|
||||
|
||||
</Vastus>
|
||||
</Saadetis>
|
||||
41813
local-sync/xmls/public-message.xml
Normal file
41813
local-sync/xmls/public-message.xml
Normal file
File diff suppressed because it is too large
Load Diff
103
ostukorv-order-xml-ferritiin+kliiniline_vereanalyys.xml
Normal file
103
ostukorv-order-xml-ferritiin+kliiniline_vereanalyys.xml
Normal file
@@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Saadetis xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="TellimusLOINC.xsd">
|
||||
<Pais>
|
||||
<Pakett versioon="20">OL</Pakett>
|
||||
<Saatja>medreport</Saatja>
|
||||
<Saaja>HTI</Saaja>
|
||||
<Aeg>2025-09-04 14:04:33</Aeg>
|
||||
<SaadetisId>1234567890</SaadetisId>
|
||||
<Email>argo@medreport.ee</Email>
|
||||
</Pais>
|
||||
<Tellimus cito="EI">
|
||||
<ValisTellimuseId>1234567890</ValisTellimuseId>
|
||||
<!--<TellijaAsutus>-->
|
||||
<Asutus tyyp="TELLIJA">
|
||||
<AsutuseId>16381793</AsutuseId>
|
||||
<AsutuseNimi>MedReport OÜ</AsutuseNimi>
|
||||
<AsutuseKood>TSU</AsutuseKood>
|
||||
<Telefon>+37258871517</Telefon>
|
||||
</Asutus>
|
||||
<!--<TeostajaAsutus>-->
|
||||
<Asutus tyyp="TEOSTAJA">
|
||||
<AsutuseId>11107913</AsutuseId>
|
||||
<AsutuseNimi>Synlab HTI Tallinn</AsutuseNimi>
|
||||
<AsutuseKood>SLA</AsutuseKood>
|
||||
<AllyksuseNimi>Synlab HTI Tallinn</AllyksuseNimi>
|
||||
<Telefon>+3723417123</Telefon>
|
||||
</Asutus>
|
||||
<!--<TellijaIsik>-->
|
||||
<Personal tyyp="TELLIJA" jarjenumber="1">
|
||||
<PersonalOID>1.3.6.1.4.1.28284.6.2.4.9</PersonalOID>
|
||||
<PersonalKood>1234567890</PersonalKood>
|
||||
<PersonalPerekonnaNimi>Doe</PersonalPerekonnaNimi>
|
||||
<PersonalEesNimi>John</PersonalEesNimi>
|
||||
<Telefon>+3721234567890</Telefon>
|
||||
</Personal>
|
||||
<TellijaMarkused></TellijaMarkused>
|
||||
<Patsient>
|
||||
<IsikukoodiOID>1.3.6.1.4.1.28284.6.2.2.1</IsikukoodiOID>
|
||||
<Isikukood>1234567890</Isikukood>
|
||||
<PerekonnaNimi>Doe</PerekonnaNimi>
|
||||
<EesNimi>John</EesNimi>
|
||||
<SynniAeg>1826-00-06</SynniAeg>
|
||||
<SuguOID>1.3.6.1.4.1.28284.6.2.3.16.2</SuguOID>
|
||||
<Sugu>M</Sugu>
|
||||
</Patsient>
|
||||
<Konfidentsiaalsus>
|
||||
<PatsiendileOID>2.16.840.1.113883.5.25</PatsiendileOID>
|
||||
<Patsiendile>N</Patsiendile>
|
||||
<ArstileOID>1.3.6.1.4.1.28284.6.2.2.39.1</ArstileOID>
|
||||
<Arstile>N</Arstile>
|
||||
<EsindajaleOID>1.3.6.1.4.1.28284.6.2.2.37.1</EsindajaleOID>
|
||||
<Esindajale>N</Esindajale>
|
||||
</Konfidentsiaalsus>
|
||||
|
||||
<Proov>
|
||||
<ProovinouIdOID>1.3.6.1.4.1.28284.6.2.1.243.22</ProovinouIdOID>
|
||||
<ProovinouId>A7</ProovinouId>
|
||||
<MaterjaliTyypOID>1.3.6.1.4.1.28284.6.2.1.244.15</MaterjaliTyypOID>
|
||||
<MaterjaliTyyp>445295009</MaterjaliTyyp>
|
||||
<MaterjaliNimi>K2E/K3E-veri</MaterjaliNimi>
|
||||
<Jarjenumber>1</Jarjenumber>
|
||||
</Proov>
|
||||
<Proov>
|
||||
<ProovinouIdOID>1.3.6.1.4.1.28284.6.2.1.243.22</ProovinouIdOID>
|
||||
<ProovinouId>A2</ProovinouId>
|
||||
<MaterjaliTyypOID>1.3.6.1.4.1.28284.6.2.1.244.15</MaterjaliTyypOID>
|
||||
<MaterjaliTyyp>119364003</MaterjaliTyyp>
|
||||
<MaterjaliNimi>Seerum</MaterjaliNimi>
|
||||
<Jarjenumber>2</Jarjenumber>
|
||||
</Proov>
|
||||
<UuringuGrupp>
|
||||
<UuringuGruppId>TL10</UuringuGruppId>
|
||||
<UuringuGruppNimi>Hematoloogilised uuringud</UuringuGruppNimi>
|
||||
<Uuring>
|
||||
<UuringuElement>
|
||||
<UuringIdOID>2.16.840.1.113883.6.1</UuringIdOID>
|
||||
<UuringId>57021-8</UuringId>
|
||||
<TLyhend>B-CBC-5Diff</TLyhend>
|
||||
<KNimetus>Hemogramm 5-osalise leukogrammiga</KNimetus>
|
||||
<UuringNimi>Hemogramm</UuringNimi>
|
||||
<TellijaUuringId>4522</TellijaUuringId>
|
||||
</UuringuElement>
|
||||
<ProoviJarjenumber>1</ProoviJarjenumber>
|
||||
</Uuring>
|
||||
</UuringuGrupp>
|
||||
<UuringuGrupp>
|
||||
<UuringuGruppId>TL50</UuringuGruppId>
|
||||
<UuringuGruppNimi>Hormoon- jm. immuunuuringud</UuringuGruppNimi>
|
||||
<Uuring>
|
||||
<UuringuElement>
|
||||
<UuringIdOID>2.16.840.1.113883.6.1</UuringIdOID>
|
||||
<UuringId>2276-4</UuringId>
|
||||
<TLyhend>S,P-Fer</TLyhend>
|
||||
<KNimetus>Ferritiin</KNimetus>
|
||||
<UuringNimi>Ferritiin</UuringNimi>
|
||||
<TellijaUuringId>4605</TellijaUuringId>
|
||||
</UuringuElement>
|
||||
<ProoviJarjenumber>2</ProoviJarjenumber>
|
||||
</Uuring>
|
||||
</UuringuGrupp>
|
||||
</Tellimus>
|
||||
</Saadetis>
|
||||
126
ostukorv-order-xml-premiumpakett3tootega.xml
Normal file
126
ostukorv-order-xml-premiumpakett3tootega.xml
Normal file
@@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Saadetis xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="TellimusLOINC.xsd">
|
||||
<Pais>
|
||||
<Pakett versioon="20">OL</Pakett>
|
||||
<Saatja>medreport</Saatja>
|
||||
<Saaja>HTI</Saaja>
|
||||
<Aeg>2025-09-04 14:17:12</Aeg>
|
||||
<SaadetisId>1234567890</SaadetisId>
|
||||
<Email>argo@medreport.ee</Email>
|
||||
</Pais>
|
||||
<Tellimus cito="EI">
|
||||
<ValisTellimuseId>1234567890</ValisTellimuseId>
|
||||
<!--<TellijaAsutus>-->
|
||||
<Asutus tyyp="TELLIJA">
|
||||
<AsutuseId>16381793</AsutuseId>
|
||||
<AsutuseNimi>MedReport OÜ</AsutuseNimi>
|
||||
<AsutuseKood>TSU</AsutuseKood>
|
||||
<Telefon>+37258871517</Telefon>
|
||||
</Asutus>
|
||||
<!--<TeostajaAsutus>-->
|
||||
<Asutus tyyp="TEOSTAJA">
|
||||
<AsutuseId>11107913</AsutuseId>
|
||||
<AsutuseNimi>Synlab HTI Tallinn</AsutuseNimi>
|
||||
<AsutuseKood>SLA</AsutuseKood>
|
||||
<AllyksuseNimi>Synlab HTI Tallinn</AllyksuseNimi>
|
||||
<Telefon>+3723417123</Telefon>
|
||||
</Asutus>
|
||||
<!--<TellijaIsik>-->
|
||||
<Personal tyyp="TELLIJA" jarjenumber="1">
|
||||
<PersonalOID>1.3.6.1.4.1.28284.6.2.4.9</PersonalOID>
|
||||
<PersonalKood>1234567890</PersonalKood>
|
||||
<PersonalPerekonnaNimi>Doe</PersonalPerekonnaNimi>
|
||||
<PersonalEesNimi>John</PersonalEesNimi>
|
||||
<Telefon>+3721234567890</Telefon>
|
||||
</Personal>
|
||||
<TellijaMarkused></TellijaMarkused>
|
||||
<Patsient>
|
||||
<IsikukoodiOID>1.3.6.1.4.1.28284.6.2.2.1</IsikukoodiOID>
|
||||
<Isikukood>1234567890</Isikukood>
|
||||
<PerekonnaNimi>Doe</PerekonnaNimi>
|
||||
<EesNimi>John</EesNimi>
|
||||
<SynniAeg>1826-00-06</SynniAeg>
|
||||
<SuguOID>1.3.6.1.4.1.28284.6.2.3.16.2</SuguOID>
|
||||
<Sugu>M</Sugu>
|
||||
</Patsient>
|
||||
<Konfidentsiaalsus>
|
||||
<PatsiendileOID>2.16.840.1.113883.5.25</PatsiendileOID>
|
||||
<Patsiendile>N</Patsiendile>
|
||||
<ArstileOID>1.3.6.1.4.1.28284.6.2.2.39.1</ArstileOID>
|
||||
<Arstile>N</Arstile>
|
||||
<EsindajaleOID>1.3.6.1.4.1.28284.6.2.2.37.1</EsindajaleOID>
|
||||
<Esindajale>N</Esindajale>
|
||||
</Konfidentsiaalsus>
|
||||
|
||||
<Proov>
|
||||
<ProovinouIdOID>1.3.6.1.4.1.28284.6.2.1.243.22</ProovinouIdOID>
|
||||
<ProovinouId>A9</ProovinouId>
|
||||
<MaterjaliTyypOID>1.3.6.1.4.1.28284.6.2.1.244.15</MaterjaliTyypOID>
|
||||
<MaterjaliTyyp>2491000181101</MaterjaliTyyp>
|
||||
<MaterjaliNimi>Glükolüüsi inhibiitoriga plasma</MaterjaliNimi>
|
||||
<Jarjenumber>1</Jarjenumber>
|
||||
</Proov>
|
||||
<Proov>
|
||||
<ProovinouIdOID>1.3.6.1.4.1.28284.6.2.1.243.22</ProovinouIdOID>
|
||||
<ProovinouId>A2</ProovinouId>
|
||||
<MaterjaliTyypOID>1.3.6.1.4.1.28284.6.2.1.244.15</MaterjaliTyypOID>
|
||||
<MaterjaliTyyp>119364003</MaterjaliTyyp>
|
||||
<MaterjaliNimi>Seerum</MaterjaliNimi>
|
||||
<Jarjenumber>2</Jarjenumber>
|
||||
</Proov>
|
||||
<Proov>
|
||||
<ProovinouIdOID>1.3.6.1.4.1.28284.6.2.1.243.22</ProovinouIdOID>
|
||||
<ProovinouId>A2</ProovinouId>
|
||||
<MaterjaliTyypOID>1.3.6.1.4.1.28284.6.2.1.244.15</MaterjaliTyypOID>
|
||||
<MaterjaliTyyp>119364003</MaterjaliTyyp>
|
||||
<MaterjaliNimi>Seerum</MaterjaliNimi>
|
||||
<Jarjenumber>3</Jarjenumber>
|
||||
</Proov>
|
||||
<UuringuGrupp>
|
||||
<UuringuGruppId>TL40</UuringuGruppId>
|
||||
<UuringuGruppNimi>Kliinilise keemia uuringud</UuringuGruppNimi>
|
||||
<Uuring>
|
||||
<UuringuElement>
|
||||
<UuringIdOID>2.16.840.1.113883.6.1</UuringIdOID>
|
||||
<UuringId>14771-0</UuringId>
|
||||
<TLyhend>fS,fP-Gluc</TLyhend>
|
||||
<KNimetus>Glükoos paastuseerumis/-plasmas</KNimetus>
|
||||
<UuringNimi>Glükoos</UuringNimi>
|
||||
<TellijaUuringId>4530</TellijaUuringId>
|
||||
</UuringuElement>
|
||||
<ProoviJarjenumber>1</ProoviJarjenumber>
|
||||
</Uuring>
|
||||
</UuringuGrupp>
|
||||
<UuringuGrupp>
|
||||
<UuringuGruppId>TL40</UuringuGruppId>
|
||||
<UuringuGruppNimi>Kliinilise keemia uuringud</UuringuGruppNimi>
|
||||
<Uuring>
|
||||
<UuringuElement>
|
||||
<UuringIdOID>2.16.840.1.113883.6.1</UuringIdOID>
|
||||
<UuringId>14927-8</UuringId>
|
||||
<TLyhend>S,P-Trigl</TLyhend>
|
||||
<KNimetus>Triglütseriidid</KNimetus>
|
||||
<UuringNimi>Triglütseriidid</UuringNimi>
|
||||
<TellijaUuringId>4535</TellijaUuringId>
|
||||
</UuringuElement>
|
||||
<ProoviJarjenumber>2</ProoviJarjenumber>
|
||||
</Uuring>
|
||||
</UuringuGrupp>
|
||||
<UuringuGrupp>
|
||||
<UuringuGruppId>TL40</UuringuGruppId>
|
||||
<UuringuGruppNimi>Kliinilise keemia uuringud</UuringuGruppNimi>
|
||||
<Uuring>
|
||||
<UuringuElement>
|
||||
<UuringIdOID>2.16.840.1.113883.6.1</UuringIdOID>
|
||||
<UuringId>14798-3</UuringId>
|
||||
<TLyhend>S,P-Fe</TLyhend>
|
||||
<KNimetus>Raud</KNimetus>
|
||||
<UuringNimi>Raud</UuringNimi>
|
||||
<TellijaUuringId>4570</TellijaUuringId>
|
||||
</UuringuElement>
|
||||
<ProoviJarjenumber>3</ProoviJarjenumber>
|
||||
</Uuring>
|
||||
</UuringuGrupp>
|
||||
</Tellimus>
|
||||
</Saadetis>
|
||||
@@ -102,6 +102,7 @@ export const OauthProviders: React.FC<{
|
||||
redirectTo,
|
||||
queryParams: props.queryParams,
|
||||
scopes,
|
||||
skipBrowserRedirect: false,
|
||||
},
|
||||
} satisfies SignInWithOAuthCredentials;
|
||||
|
||||
|
||||
@@ -28,6 +28,10 @@ export const OrderSchema = z.object({
|
||||
title: z.string(),
|
||||
isPackage: z.boolean(),
|
||||
analysisOrderId: z.number(),
|
||||
productMetadata: z.object({
|
||||
analysisIdOriginal: z.string().nullable(),
|
||||
analysisResultUnit: z.string().nullable(),
|
||||
}).nullable(),
|
||||
});
|
||||
export type Order = z.infer<typeof OrderSchema>;
|
||||
|
||||
|
||||
8
run-test-sync-local.sh
Normal file → Executable file
8
run-test-sync-local.sh
Normal file → Executable file
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
MEDUSA_ORDER_ID="order_01K1TQQHZGPXKDHAH81TDSNGXR"
|
||||
MEDUSA_ORDER_ID="order_01K2JFCZ609YF5G84ZKDCBWPM6"
|
||||
|
||||
# HOSTNAME="https://test.medreport.ee"
|
||||
# JOBS_API_TOKEN="fd26ec26-70ed-11f0-9e95-431ac3b15a84"
|
||||
@@ -33,7 +33,7 @@ function sync_analysis_groups_store() {
|
||||
# Requirements
|
||||
|
||||
# 1. Sync analysis groups from Medipost to B2B
|
||||
sync_analysis_groups
|
||||
#sync_analysis_groups
|
||||
|
||||
# 2. Optional - sync all Medipost analysis groups from B2B to Medusa (or add manually)
|
||||
#sync_analysis_groups_store
|
||||
@@ -41,7 +41,7 @@ sync_analysis_groups
|
||||
# 3. Set up products configurations in Medusa so B2B "Telli analüüs" page shows the product and you can do payment flow
|
||||
|
||||
# 4. After payment is done, run `send_medipost_test_response` to send the fake test results to Medipost
|
||||
# send_medipost_test_response
|
||||
#send_medipost_test_response
|
||||
|
||||
# 5. Run `sync_analysis_results` to sync the all new Medipost results to B2B
|
||||
# sync_analysis_results
|
||||
sync_analysis_results
|
||||
|
||||
5
scripts/build-docker.sh
Normal file
5
scripts/build-docker.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
docker build -t medreport-b2b:latest .
|
||||
|
||||
# Get size of built image and display it
|
||||
@@ -105,9 +105,9 @@ file_size_limit = "50MiB"
|
||||
enabled = true
|
||||
# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used
|
||||
# in emails.
|
||||
site_url = "http://127.0.0.1:3000"
|
||||
site_url = "http://localhost:3000"
|
||||
# A list of *exact* URLs that auth providers are permitted to redirect to post authentication.
|
||||
additional_redirect_urls = ["https://127.0.0.1:3000","http://localhost:3000/auth/callback", "http://localhost:3000/update-password"]
|
||||
additional_redirect_urls = ["https://127.0.0.1:3000","http://127.0.0.1:3000","http://localhost:3000","http://localhost:3000/auth/callback", "http://localhost:3000/update-password"]
|
||||
# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week).
|
||||
jwt_expiry = 3600
|
||||
# If disabled, the refresh token will never expire.
|
||||
@@ -269,6 +269,14 @@ url = ""
|
||||
# If enabled, the nonce check will be skipped. Required for local sign in with Google auth.
|
||||
skip_nonce_check = false
|
||||
|
||||
[auth.external.keycloak]
|
||||
enabled = true
|
||||
client_id = "env(SUPABASE_AUTH_CLIENT_ID)"
|
||||
secret = "env(SUPABASE_AUTH_KEYCLOAK_SECRET)"
|
||||
redirect_uri = "env(SUPABASE_AUTH_KEYCLOAK_CALLBACK_URL)"
|
||||
url = "env(SUPABASE_AUTH_KEYCLOAK_URL)"
|
||||
skip_nonce_check = true
|
||||
|
||||
# Use Firebase Auth as a third-party provider alongside Supabase Auth.
|
||||
[auth.third_party.firebase]
|
||||
enabled = false
|
||||
|
||||
64
supabase/sql/setup-cron-job.sql
Normal file
64
supabase/sql/setup-cron-job.sql
Normal file
@@ -0,0 +1,64 @@
|
||||
-- Enable required extensions for cron jobs and HTTP requests
|
||||
create extension if not exists pg_cron;
|
||||
create extension if not exists pg_net;
|
||||
|
||||
-- Enable the cron extension to be used in all databases
|
||||
-- This needs to be run with superuser privileges or via Supabase Dashboard
|
||||
grant usage on schema cron to postgres;
|
||||
grant all privileges on all tables in schema cron to postgres;
|
||||
|
||||
-- Function to safely schedule the cron job with environment variables
|
||||
-- This approach allows for easier management and avoids hardcoding sensitive values
|
||||
create or replace function schedule_sync_analysis_results_cron(
|
||||
api_url text,
|
||||
api_token text
|
||||
) returns text as $$
|
||||
declare
|
||||
job_exists boolean;
|
||||
begin
|
||||
-- Check if job already exists
|
||||
select exists(
|
||||
select 1 from cron.job
|
||||
where jobname = 'sync-analysis-results-every-15-minutes'
|
||||
) into job_exists;
|
||||
|
||||
-- If job exists, unschedule it first
|
||||
if job_exists then
|
||||
perform cron.unschedule('sync-analysis-results-every-15-minutes');
|
||||
end if;
|
||||
|
||||
-- Schedule the new job
|
||||
perform cron.schedule(
|
||||
'sync-analysis-results-every-15-minutes',
|
||||
'*/15 * * * *', -- Every 15 minutes
|
||||
format(
|
||||
'select net.http_post(url := ''%s/api/job/sync-analysis-results'', headers := jsonb_build_object(''Content-Type'', ''application/json'', ''x-jobs-api-key'', ''%s''), body := jsonb_build_object(''triggered_by'', ''supabase_cron'', ''timestamp'', now())) as request_id;',
|
||||
api_url, api_token
|
||||
)
|
||||
);
|
||||
|
||||
return 'Cron job scheduled successfully';
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- Example usage (replace with your actual values):
|
||||
-- select schedule_sync_analysis_results_cron(
|
||||
-- 'https://your-domain.com',
|
||||
-- 'your-jobs-api-token-here'
|
||||
-- );
|
||||
|
||||
-- Utility queries for managing the cron job:
|
||||
|
||||
-- 1. Check if the job is scheduled
|
||||
-- select * from cron.job where jobname = 'sync-analysis-results-every-15-minutes';
|
||||
|
||||
-- 2. View job execution history
|
||||
-- select * from cron.job_run_details
|
||||
-- where jobid = (select jobid from cron.job where jobname = 'sync-analysis-results-every-15-minutes')
|
||||
-- order by start_time desc limit 10;
|
||||
|
||||
-- 3. Unschedule the job if needed
|
||||
-- select cron.unschedule('sync-analysis-results-every-15-minutes');
|
||||
|
||||
-- 4. Check all scheduled jobs
|
||||
-- select jobid, schedule, active, jobname from cron.job;
|
||||
122
supabase/sql/supabase-cron-setup.md
Normal file
122
supabase/sql/supabase-cron-setup.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Supabase Cron Job Setup for sync-analysis-results
|
||||
|
||||
This document explains how to set up a Supabase cron job to automatically call the `sync-analysis-results` API endpoint every 15 minutes.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Supabase project with database access
|
||||
2. Your application deployed and accessible via a public URL
|
||||
3. `JOBS_API_TOKEN` environment variable configured
|
||||
|
||||
## Setup Steps
|
||||
|
||||
### 1. Enable Required Extensions
|
||||
|
||||
First, enable the required PostgreSQL extensions in your Supabase project:
|
||||
|
||||
```sql
|
||||
create extension if not exists pg_cron;
|
||||
create extension if not exists pg_net;
|
||||
```
|
||||
|
||||
You can run this either:
|
||||
- In the Supabase Dashboard → Database → SQL Editor
|
||||
- Or deploy the migration file: `supabase/migrations/setup_sync_analysis_results_cron.sql`
|
||||
|
||||
### 2. Schedule the Cron Job
|
||||
|
||||
Use the helper function to schedule the cron job with your specific configuration:
|
||||
|
||||
```sql
|
||||
select schedule_sync_analysis_results_cron(
|
||||
'https://your-actual-domain.com', -- Replace with your API URL
|
||||
'your-actual-jobs-api-token' -- Replace with your JOBS_API_TOKEN
|
||||
);
|
||||
```
|
||||
|
||||
### 3. Verify the Setup
|
||||
|
||||
Check if the job was scheduled successfully:
|
||||
|
||||
```sql
|
||||
select * from cron.job where jobname = 'sync-analysis-results-every-15-minutes';
|
||||
```
|
||||
|
||||
## Management Commands
|
||||
|
||||
### View Job Execution History
|
||||
|
||||
```sql
|
||||
select * from cron.job_run_details
|
||||
where jobid = (select jobid from cron.job where jobname = 'sync-analysis-results-every-15-minutes')
|
||||
order by start_time desc limit 10;
|
||||
```
|
||||
|
||||
### Check All Scheduled Jobs
|
||||
|
||||
```sql
|
||||
select jobid, schedule, active, jobname from cron.job;
|
||||
```
|
||||
|
||||
### Unschedule the Job
|
||||
|
||||
```sql
|
||||
select cron.unschedule('sync-analysis-results-every-15-minutes');
|
||||
```
|
||||
|
||||
## Configuration Details
|
||||
|
||||
- **Schedule**: `*/15 * * * *` (every 15 minutes)
|
||||
- **HTTP Method**: POST
|
||||
- **Headers**:
|
||||
- `Content-Type: application/json`
|
||||
- `x-jobs-api-key: YOUR_JOBS_API_TOKEN`
|
||||
- **Body**: JSON with metadata about the cron trigger
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **API Token**: Store your `JOBS_API_TOKEN` securely and never commit it to version control
|
||||
2. **Network Access**: Ensure your Supabase instance can reach your deployed application
|
||||
3. **Rate Limiting**: The 15-minute interval should be appropriate for your use case
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Job Not Running
|
||||
|
||||
1. Check if extensions are enabled:
|
||||
```sql
|
||||
select * from pg_extension where extname in ('pg_cron', 'pg_net');
|
||||
```
|
||||
|
||||
2. Verify job is active:
|
||||
```sql
|
||||
select * from cron.job where jobname = 'sync-analysis-results-every-15-minutes';
|
||||
```
|
||||
|
||||
3. Check for execution errors:
|
||||
```sql
|
||||
select * from cron.job_run_details
|
||||
where jobid = (select jobid from cron.job where jobname = 'sync-analysis-results-every-15-minutes')
|
||||
and status = 'failed'
|
||||
order by start_time desc;
|
||||
```
|
||||
|
||||
### API Authentication Issues
|
||||
|
||||
1. Verify your `JOBS_API_TOKEN` is correct
|
||||
2. Test the API endpoint manually:
|
||||
```bash
|
||||
curl -X POST https://your-domain.com/api/job/sync-analysis-results \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "x-jobs-api-key: YOUR_JOBS_API_TOKEN"
|
||||
```
|
||||
|
||||
## Alternative: Using Supabase Edge Functions
|
||||
|
||||
If you prefer using Supabase Edge Functions instead of pg_cron, you can:
|
||||
|
||||
1. Create an Edge Function that calls your API
|
||||
2. Use Supabase's built-in cron triggers for Edge Functions
|
||||
3. This approach provides better logging and error handling
|
||||
|
||||
Contact your team lead for assistance with Edge Functions setup if needed.
|
||||
Reference in New Issue
Block a user