Initial scaffold: unified customer/insurance/utilities platform

Next.js + NestJS + Prisma (MySQL) monorepo replacing the legacy PHP
internal app. Includes a session-based auth module with Argon2 password
hashing and global input validation (replacing the old app's SQL
injection and plaintext password comparison), the full target Prisma
schema for customers/insurance/utilities/shared ledger/bank register,
Docker Compose + Dockerfiles, and an Access-to-staging migration
pipeline (migration/) already run against the real source databases.

See PLAN.md and RESUME.md for the full architecture and session history.
This commit is contained in:
2026-07-22 01:29:56 -07:00
commit 27118f0df2
39 changed files with 10341 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
import "reflect-metadata";
import { NestFactory } from "@nestjs/core";
import { ValidationPipe } from "@nestjs/common";
import * as session from "express-session";
import * as passport from "passport";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Every request body is validated and stripped of unknown fields before it
// reaches a controller — this is the structural replacement for the old
// app's complete lack of input validation (src/core/db.php took every
// $_POST field straight into a SQL string).
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
forbidNonWhitelisted: true,
transform: true,
})
);
const sessionSecret = process.env.SESSION_SECRET;
if (!sessionSecret) {
throw new Error("SESSION_SECRET must be set (see .env.example)");
}
app.use(
session({
secret: sessionSecret,
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
maxAge: 1000 * 60 * 60 * 8, // 8-hour session, matches a staff workday
},
})
);
app.use(passport.initialize());
app.use(passport.session());
app.enableCors({ credentials: true, origin: process.env.WEB_ORIGIN ?? "http://localhost:3000" });
const port = process.env.PORT ? Number(process.env.PORT) : 3001;
await app.listen(port);
}
bootstrap();