Prepare for production deployment

This commit is contained in:
Fred Boniface 2025-06-26 20:17:45 +01:00
parent b6c590eab0
commit 9a9bd8b71b
5 changed files with 74 additions and 12 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
node_modules
.env

30
src/database.ts Normal file
View File

@ -0,0 +1,30 @@
import mongoose from "mongoose";
let isConnected = false;
export async function initDb(): Promise<void> {
if (isConnected || mongoose.connection.readyState >= 1) return;
const {
MONGO_HOST = 'localhost',
MONGO_USER,
MONGO_PASS,
MONGO_NAME = 'tracreport',
MONGO_OPTS = '',
} = process.env
const credentials = MONGO_USER && MONGO_PASS
? `${encodeURIComponent(MONGO_USER)}:${encodeURIComponent(MONGO_PASS)}@`
: '';
const MONGO_URI = `mongodb://${credentials}${MONGO_HOST}/${MONGO_NAME}${MONGO_OPTS ? '?' + MONGO_OPTS : ''}`;
try {
await mongoose.connect(MONGO_URI);
isConnected = true;
console.log('✅ MongoDB connected');
} catch (err) {
console.error('❌ MongoDB connection error:', err)
process.exit(1);
}
}

View File

@ -1,12 +1,13 @@
import nodemailer from 'nodemailer';
import type { Transporter, SendMailOptions } from 'nodemailer';
import { Report, Report as ReportSchema } from './models/report';
interface Fault {
export interface Fault {
coach: string;
zone: string;
}
interface Report {
export interface Report {
unitNumber: string;
reported: string;
comments: string;
@ -40,21 +41,15 @@ export async function handleFormData(data) {
}
}
submit(report);
sendMail(report);
}
async function submit(report: Report): Promise<void> {
console.log(report);
// Send to database
// Send to email
sendToDatabase(report);
}
async function sendMail(report: Report): Promise<void> {
const transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT || '587'),
secure: true,
secure: false,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
@ -70,8 +65,8 @@ async function sendMail(report: Report): Promise<void> {
text: `A report has been submitted for unit ${report.unitNumber}.\n\n` +
`Timestamp: ${report.utcTimestamp}\n\n` +
`Faults:\n${faultList}\n\n` +
`Reported to Maintenance: ${report.reported}` +
`Comments:\n${report.comments} || 'None'`
`Reported to Maintenance: ${report.reported}\n\n` +
`Comments:\n${report.comments || 'None'}`
};
try {
@ -80,4 +75,18 @@ async function sendMail(report: Report): Promise<void> {
} catch (err) {
console.error('❌ Failed to send email:', err);
}
}
async function sendToDatabase(report: Report) {
const newReport = new ReportSchema({
unitNumber: report.unitNumber,
reported: report.reported,
comments: report.comments,
utcTimestamp: report.utcTimestamp,
faults: report.faults
});
await newReport.save();
console.log("Report saved to Database");
}

View File

@ -1,9 +1,12 @@
import express, { Request, Response } from "express";
import { handleFormData } from "./formHandler";
import { initDb } from "./database";
const app = express();
const port = process.env.port || 3000;
initDb();
app.use(express.static('static'));
app.use(express.json());

19
src/models/report.ts Normal file
View File

@ -0,0 +1,19 @@
import { Schema, model, Document } from "mongoose";
import type { Report as ReportType, Fault as FaultType } from "../formHandler";
interface ReportDocument extends ReportType, Document {}
const FaultSchema = new Schema<FaultType>({
coach: { type: String, required: true },
zone: { type: String, required: true },
}, { _id: false }); // Prevents Mongoose from auto-generating _id for each fault
const ReportSchema = new Schema<ReportDocument>({
unitNumber: { type: String, required: true },
reported: { type: String, required: true },
comments: { type: String, required: true },
utcTimestamp: { type: String, required: true },
faults: { type: [FaultSchema], required: true },
});
export const Report = model<ReportDocument>('Report', ReportSchema);