enable dev|prod envs with simpler env vars system

This commit is contained in:
JCEEE
2026-08-06 18:09:47 +01:00
parent 2fc1668356
commit 4f384426d0
37 changed files with 447 additions and 256 deletions
+2 -2
View File
@@ -3,10 +3,10 @@
"private": true,
"type": "module",
"scripts": {
"dev": "tsx watch src/index.ts",
"dev": "tsx watch --env-file-if-exists=../.env src/index.ts",
"build": "esbuild src/index.ts --bundle --platform=node --format=esm --outfile=dist/index.js",
"start": "node dist/index.js",
"seed": "tsx scripts/seed.ts"
"seed": "tsx --env-file-if-exists=../.env scripts/seed.ts"
},
"dependencies": {
"@hono/node-server": "^1.13.0",
+3 -5
View File
@@ -1,6 +1,4 @@
import { SERVER_IP, PB_PORT, PB_EMAIL, PB_PASSWORD } from "../../config.ts";
const PB_ENDPOINT = `http://${SERVER_IP}:${PB_PORT}`;
import { PB_ENDPOINT, PB_EMAIL, PB_PASSWORD } from "../src/env.ts";
interface FieldDef {
name: string;
@@ -121,8 +119,8 @@ async function main() {
ids.fams = await createCollection(token, {
name: "fams",
type: "base",
listRule: "",
viewRule: "",
listRule: null,
viewRule: null,
createRule: null,
updateRule: null,
deleteRule: null,
+14
View File
@@ -0,0 +1,14 @@
// Runtime env for the proxy. Same dev/prod split as the frontend: dev connects
// to the dev machine's PocketBase at SERVER_IP, prod connects to the
// container-internal loopback PB. Ports come from config.ts (single source).
//
// Env loading: dev uses `tsx --env-file=../.env` (see package.json) like vite
// does for the frontend; prod (docker) injects env via compose and has no .env,
// so SERVER_IP is unset → loopback below.
const SERVER_IP = process.env.SERVER_IP;
export const PB_ENDPOINT = SERVER_IP
? `http://${SERVER_IP}:8090`
: `http://127.0.0.1:8090`;
export const PB_EMAIL = process.env.PB_EMAIL || "debug@famchamp.dev";
export const PB_PASSWORD = process.env.PB_PASSWORD || "debug123";
+3 -3
View File
@@ -3,6 +3,7 @@ import { serve } from "@hono/node-server";
import { Hono } from "hono";
import { pb } from "./pb.ts";
import { migrate } from "./migrate.ts";
import { PROXY_PORT } from "../../config.ts";
import {
weekStart as tzWeekStart,
addDaysStr,
@@ -2453,11 +2454,10 @@ app.get("/api/chat/me", async (c) => {
// ── Start server ─────────────────────────────────────────
const port = parseInt(process.env.PROXY_PORT || "3456", 10);
const SERVER_IP = "192.168.1.225";
const port = parseInt(process.env.PROXY_PORT || PROXY_PORT, 10);
serve({ fetch: app.fetch, port }, async (info) => {
console.log(`Hono proxy listening on ${SERVER_IP}:${info.port}`);
console.log(`Hono proxy listening on 0.0.0.0:${info.port}`);
try {
await migrate();
} catch (e) {
+16
View File
@@ -128,6 +128,8 @@ async function ensureSchema(): Promise<void> {
jsonField("seasons"),
]),
))!;
// fams is sensitive → superadmin-only (proxy/server reads). Not public.
await updateCollection(famsId, { viewRule: null, listRule: null });
await createCollection(
colDef("bonus_templates", [
rel("famId", famsId, true),
@@ -280,6 +282,20 @@ export async function migrate(): Promise<void> {
await ensureSchema();
// ── 0. Lock fams to superadmin-only (sensitive; read via proxy/server) ──
{
const famsCol = await getCollection("fams");
if (famsCol) {
const rules = { viewRule: null, listRule: null };
if (famsCol.viewRule !== null || famsCol.listRule !== null) {
console.log("[migrate] Locking fams collection to superadmin-only...");
await updateCollection(famsCol.id, rules);
} else {
console.log(" ↳ fams already superadmin-only");
}
}
}
// ── 1. Create bonus_configs if missing ──
const existing = await getCollection("bonus_configs");
if (!existing) {