diff --git a/src/lib/db/db.ts b/src/lib/db/db.ts
new file mode 100644
index 0000000..32e4191
--- /dev/null
+++ b/src/lib/db/db.ts
@@ -0,0 +1,37 @@
+import mongoose from 'mongoose';
+import { MONGO_URL } from '$env/static/private';
+/*
+ 0 - disconnected
+ 1 - connected
+ 2 - connecting
+ 3 - disconnecting
+ 4 - uninitialized
+*/
+const mongoConnection = {
+ isConnected: 0,
+};
+
+export const dbConnect = async () => {
+ if (mongoConnection.isConnected === 1) {
+ return;
+ }
+
+ if (mongoose.connections.length > 0) {
+ mongoConnection.isConnected = mongoose.connections[0].readyState;
+ if (mongoConnection.isConnected === 1) {
+ return;
+ }
+
+ await mongoose.disconnect();
+ }
+ await mongoose.connect(MONGO_URL ?? '');
+ mongoConnection.isConnected = 1;
+};
+
+export const dbDisconnect = async () => {
+ if (process.env.NODE_ENV === 'development') return;
+ if (mongoConnection.isConnected === 0) return;
+
+ await mongoose.disconnect();
+ mongoConnection.isConnected = 0;
+};
diff --git a/src/lib/models/Payment.ts b/src/lib/models/Payment.ts
new file mode 100644
index 0000000..c0b8379
--- /dev/null
+++ b/src/lib/models/Payment.ts
@@ -0,0 +1,25 @@
+import mongoose from 'mongoose';
+
+const PaymentSchema = new mongoose.Schema(
+ {
+ type: {type: String, required: true, enum: ['payment', 'reimbursement']},
+ name: {type: String, required: true},
+ category : {type: String, required: false,},
+ date: {type: Date, default: Date.now},
+ images: [ {
+ mediapath: {type: String, required: false},
+ }],
+ description: {type: String, required: false},
+ note: {type: String, required: false},
+ tags : [String],
+ original_amount: {type: Number, required: true},
+ total_amount: {type: Number, required: true},
+ personal_amounts: [{
+ user: {type:String, required: true},
+ amount: {type: Number, required: true, default:0}
+ }],
+ currency: {type: String, required: true, default: 'CHF'},
+ }, {timestamps: true}
+);
+
+export const Payment= mongoose.model("Payment", PaymentSchema);
diff --git a/src/routes/api/cospend/+server.ts b/src/routes/api/cospend/+server.ts
new file mode 100644
index 0000000..8b28b5f
--- /dev/null
+++ b/src/routes/api/cospend/+server.ts
@@ -0,0 +1,96 @@
+import type { RequestHandler } from '@sveltejs/kit';
+import fs from 'fs';
+import path from 'path';
+import { mkdir } from 'fs/promises';
+import { Payment } from '$lib/models/Payment'; // adjust path as needed
+import { dbConnect, dbDisconnect } from '$lib/db/db';
+
+const UPLOAD_DIR = '/var/lib/www/static/test';
+const BASE_CURRENCY = 'CHF'; // Default currency
+
+export const POST: RequestHandler = async ({ request, locals }) => {
+ const formData = await request.formData();
+
+ try {
+ const name = formData.get('name') as string;
+ const category = formData.get('category') as string;
+ const date= new Date(formData.get('date') as string);
+ const description = formData.get('description') as string;
+ const note = formData.get('note') as string;
+ const tags = JSON.parse(formData.get('tags') as string) as string[];
+ let currency = formData.get('currency') as string;
+ let original_amount = parseFloat(formData.get('original_amount') as string);
+ let total_amount = NaN;
+
+ // if currency is not BASE_CURRENCY, fetch current conversion rate using frankfurter API and date in YYYY-MM-DD format
+ if (!currency || currency === BASE_CURRENCY) {
+ currency = BASE_CURRENCY;
+ total_amount = parseFloat(formData.get('total_amount') as string);
+ } else {
+ const date_fmt = date.toISOString().split('T')[0]; // Convert date to YYYY-MM-DD format
+ // Fetch conversion rate logic here (not implemented in this example)
+ const res = await fetch(`https://api.frankfurter.app/${date_fmt}?from=${currency}&to=${BASE_CURRENCY}`)
+ const { result } = await res.json();
+ if (!result || !result[BASE_CURRENCY]) {
+ return new Response(JSON.stringify({ message: 'Currency conversion failed.' }), { status: 400 });
+ }
+ // Assuming you want to convert the total amount to BASE_CURRENCY
+ const conversionRate = parseFloat(result.rates[BASE_CURRENCY]);
+ alert(`Conversion rate from ${currency} to ${BASE_CURRENCY} on ${date_fmt}: ${conversionRate}`);
+ total_amount = original_amount * conversionRate;
+ }
+
+ const personal_amounts = JSON.parse(formData.get('personal_amounts') as string) as { user: string, amount: number }[];
+
+
+ if (!name || isNaN(total_amount)) {
+ return new Response(JSON.stringify({ message: 'Invalid required fields.' }), { status: 400 });
+ }
+
+ // await mkdir(UPLOAD_DIR, { recursive: true });
+
+ const images: { mediapath: string }[] = [];
+ const imageFiles = formData.getAll('images') as File[];
+
+ for (const file of imageFiles) {
+ const arrayBuffer = await file.arrayBuffer();
+ const buffer = Buffer.from(arrayBuffer);
+ const safeName = `${Date.now()}_${file.name.replace(/[^a-zA-Z0-9_.-]/g, '_')}`;
+ const fullPath = path.join(UPLOAD_DIR, safeName);
+ //fs.writeFileSync(fullPath, buffer);
+ images.push({ mediapath: `/static/test/${safeName}` });
+ }
+
+ await dbConnect();
+ const payment = new Payment({
+ name,
+ category,
+ date,
+ description,
+ note,
+ tags,
+ total_amount,
+ original_amount,
+ currency,
+ personal_amounts,
+ images
+ });
+
+
+ // let auth = await locals.auth();
+ // // if(!auth){
+ // throw error(401, "Not logged in")
+ // }
+
+ try{
+ await Payment.create(payment);
+ } catch(e){
+ throw error(400, e)
+ }
+ await dbDisconnect();
+ return new Response(JSON.stringify({ message: 'Payment event created successfully.' }), { status: 201 });
+ } catch (err) {
+ console.error(err);
+ return new Response(JSON.stringify({ message: 'Error processing request.' }), { status: 500 });
+ }
+};
diff --git a/src/routes/cospend/+layout.server.ts b/src/routes/cospend/+layout.server.ts
new file mode 100644
index 0000000..f4f4110
--- /dev/null
+++ b/src/routes/cospend/+layout.server.ts
@@ -0,0 +1,7 @@
+import type { PageServerLoad } from "./$types"
+
+export const load : PageServerLoad = (async ({locals}) => {
+ return {
+ session: await locals.auth(),
+ }
+});
diff --git a/src/routes/cospend/+layout.svelte b/src/routes/cospend/+layout.svelte
new file mode 100644
index 0000000..5f13278
--- /dev/null
+++ b/src/routes/cospend/+layout.svelte
@@ -0,0 +1,18 @@
+
+
+
+