Shit ton of changes in changing and upgrading to use svk's modern features (observability, remote functions)

This commit is contained in:
user
2026-02-28 18:40:50 +02:00
parent f520e8842f
commit d9e89a345e
14 changed files with 1907 additions and 146 deletions

View File

@@ -0,0 +1,7 @@
# Laws
This document defines the laws, principles, and rule sets that govern this codebase. Any agent or developer making changes has to adhere to these rules.
Before starting off Read the README.md file to understand the project's goals and objectives.
TODO HAVE TO WRITE THESE

View File

@@ -1,5 +1,3 @@
# bare web application monorepo
# Illusory MAPP
for practice and showcase purpose
---
An internal automation platform built collaboratively. The premise is simple: aggregate data from each member's personal devices — mobile and otherwise — into a single centralized hub, then execute complex group-based automations on top of that collective data. The end goal is a shared automation center where the group's combined device data drives coordinated, programmable workflows.

View File

@@ -16,14 +16,21 @@
"test:unit": "vitest"
},
"dependencies": {
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/auto-instrumentations-node": "^0.70.1",
"@opentelemetry/exporter-metrics-otlp-proto": "^0.212.0",
"@opentelemetry/exporter-trace-otlp-proto": "^0.212.0",
"@opentelemetry/sdk-node": "^0.212.0",
"@pkg/db": "workspace:*",
"@pkg/logger": "workspace:*",
"@pkg/logic": "workspace:*",
"@pkg/result": "workspace:*",
"@pkg/settings": "workspace:*",
"@tanstack/svelte-query": "^6.0.18",
"better-auth": "^1.4.20",
"date-fns": "^4.1.0",
"hono": "^4.11.1",
"import-in-the-middle": "^3.0.0",
"marked": "^17.0.1",
"nanoid": "^5.1.6",
"neverthrow": "^8.2.0",

View File

@@ -0,0 +1,19 @@
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
import { createAddHookMessageChannel } from "import-in-the-middle";
import { NodeSDK } from "@opentelemetry/sdk-node";
import { settings } from "@pkg/settings";
import { register } from "node:module";
const { registerOptions } = createAddHookMessageChannel();
register("import-in-the-middle/hook.mjs", import.meta.url, registerOptions);
const sdk = new NodeSDK({
serviceName: settings.appName,
traceExporter: new OTLPTraceExporter({
// url: settings.otelExporterOtlpHttpEndpoint,
}),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();

View File

@@ -1,7 +1,7 @@
import { UserRoleMap } from "@pkg/logic/domains/user/data";
import { user } from "@pkg/db/schema/better.auth.schema";
import type { RequestHandler } from "./$types";
import { env } from "$env/dynamic/private";
import { settings } from "@pkg/settings";
import { logger } from "@pkg/logger";
import { db, eq } from "@pkg/db";
import { nanoid } from "nanoid";
@@ -10,7 +10,7 @@ import * as v from "valibot";
function isAuthorized(authHeader?: string | null) {
if (!authHeader) return false;
const authToken = authHeader.toString().replace("Bearer ", "");
return authToken === env.DEBUG_API_KEY;
return authToken === settings.debugKey;
}
export const GET: RequestHandler = async ({ request }) => {

View File

@@ -1,13 +1,13 @@
import { redirect } from "@sveltejs/kit";
import type { PageServerLoad } from "./$types";
import { auth } from "@pkg/logic/domains/auth/config.base";
import type { PageServerLoad } from "./$types";
import { redirect } from "@sveltejs/kit";
export const load = (async (c) => {
const sess = await auth.api.getSession({
headers: c.request.headers,
});
const sess = await auth.api.getSession({
headers: c.request.headers,
});
if (!!sess && !!sess.user && !!sess.session) {
return redirect(302, "/");
}
if (!!sess && !!sess.user && !!sess.session) {
return redirect(302, "/");
}
}) satisfies PageServerLoad;

View File

@@ -3,17 +3,17 @@ import adapter from "@sveltejs/adapter-node";
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://svelte.dev/docs/kit/integrations
// for more information about preprocessors
preprocess: vitePreprocess(),
kit: {
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
adapter: adapter({
out: "build",
}),
adapter: adapter({ out: "build" }),
experimental: {
remoteFunctions: true,
tracing: { server: true },
instrumentation: { server: true },
},
},
compilerOptions: {
experimental: { async: true },
},
};

View File

@@ -1,5 +1,5 @@
{
"id": "1bb75845-f9cf-41a0-96ec-10c66fdc34d6",
"id": "333bfb88-9996-4dab-bbf5-724a6eadd745",
"prevId": "00000000-0000-0000-0000-000000000000",
"version": "7",
"dialect": "postgresql",

View File

@@ -5,8 +5,8 @@
{
"idx": 0,
"version": "7",
"when": 1769954723767,
"tag": "0000_woozy_mother_askani",
"when": 1772288650927,
"tag": "0000_lucky_karma",
"breakpoints": true
}
]

View File

@@ -40,7 +40,7 @@ const colors = {
const level = () => {
const envLevel = process.env.LOG_LEVEL?.toLowerCase();
if (envLevel && envLevel in levels) {
if (envLevel && envLevel in Object.keys(levels)) {
return envLevel;
}
return settings.isDevelopment ? "debug" : "warn";

View File

@@ -16,6 +16,7 @@ export const settingsSchema = v.object({
databaseUrl: v.string(),
internalApiKey: v.string(),
debugKey: v.string(),
processorApiUrl: v.string(),
@@ -27,33 +28,10 @@ export const settingsSchema = v.object({
twofaRequiredHours: v.optional(v.number()),
defaultAdminEmail: v.string(),
defaultAdminPassword: v.string(),
googleClientId: v.string(),
googleClientSecret: v.string(),
resendApiKey: v.string(),
fromEmail: v.string(),
qstashUrl: v.string(),
qstashToken: v.string(),
qstashCurrentSigningKey: v.string(),
qstashNextSigningKey: v.string(),
axiomDatasetName: v.string(),
axiomApiToken: v.string(),
// R2/Object Storage settings
r2BucketName: v.string(),
r2Region: v.string(),
r2Endpoint: v.string(),
r2AccessKey: v.string(),
r2SecretKey: v.string(),
r2PublicUrl: v.optional(v.string()),
// File upload settings
maxFileSize: v.number(),
allowedMimeTypes: v.array(v.string()),
allowedExtensions: v.array(v.string()),
otelServiceName: v.string(),
otelExporterOtlpHttpEndpoint: v.string(),
});
export type Settings = v.InferOutput<typeof settingsSchema>;
@@ -75,16 +53,6 @@ function getEnvNumber(key: string, defaultValue: number): number {
return Number.isNaN(parsed) ? defaultValue : parsed;
}
/**
* Parse comma-separated string into array
*/
function parseCommaSeparated(value: string): string[] {
return value
.split(",")
.map((item) => item.trim())
.filter((item) => item.length > 0);
}
/**
* Load and validate settings from environment variables
*/
@@ -116,39 +84,11 @@ function loadSettings(): Settings {
twofaRequiredHours: getEnvNumber("TWOFA_REQUIRED_HOURS", 24),
defaultAdminEmail: getEnv("DEFAULT_ADMIN_EMAIL"),
defaultAdminPassword: getEnv("DEFAULT_ADMIN_PASSWORD"),
googleClientId: getEnv("GOOGLE_CLIENT_ID"),
googleClientSecret: getEnv("GOOGLE_CLIENT_SECRET"),
resendApiKey: getEnv("RESEND_API_KEY"),
fromEmail: getEnv("FROM_EMAIL"),
qstashUrl: getEnv("QSTASH_URL"),
qstashToken: getEnv("QSTASH_TOKEN"),
qstashCurrentSigningKey: getEnv("QSTASH_CURRENT_SIGNING_KEY"),
qstashNextSigningKey: getEnv("QSTASH_NEXT_SIGNING_KEY"),
axiomDatasetName: getEnv("AXIOM_DATASET_NAME"),
axiomApiToken: getEnv("AXIOM_API_TOKEN"),
// R2/Object Storage settings
r2BucketName: getEnv("R2_BUCKET_NAME"),
r2Region: getEnv("R2_REGION", "auto"),
r2Endpoint: getEnv("R2_ENDPOINT"),
r2AccessKey: getEnv("R2_ACCESS_KEY"),
r2SecretKey: getEnv("R2_SECRET_KEY"),
r2PublicUrl: getEnv("R2_PUBLIC_URL") || undefined,
// File upload settings
maxFileSize: getEnvNumber("MAX_FILE_SIZE", 10485760), // 10MB default
allowedMimeTypes: parseCommaSeparated(
getEnv(
"ALLOWED_MIME_TYPES",
"image/jpeg,image/png,image/webp,image/gif,application/pdf,text/plain",
),
),
allowedExtensions: parseCommaSeparated(
getEnv("ALLOWED_EXTENSIONS", "jpg,jpeg,png,webp,gif,pdf,txt"),
otelServiceName: getEnv("OTEL_SERVICE_NAME"),
otelExporterOtlpHttpEndpoint: getEnv(
"OTEL_EXPORTER_OTLP_HTTP_ENDPOINT",
),
};

1888
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,3 @@
packages:
- "apps/*"
- "packages/*"
- apps/*
- packages/*