-
Notifications
You must be signed in to change notification settings - Fork 0
Gloria backend setup #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
5b88943
20e3e3d
3a605c1
eaf4cc7
66d24d1
16d8518
e5109f8
05c7071
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,3 +48,5 @@ build | |
| .env | ||
| # Sentry Config File | ||
| .sentryclirc | ||
| uploads/* | ||
| uploads/* | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,41 +1 @@ | ||
| { | ||
| "name": "@apps/backend", | ||
| "private": true, | ||
| "type": "module", | ||
| "scripts": { | ||
| "lint": "bunx biome lint --write || true", | ||
| "check": "bunx biome check --write || true", | ||
| "format": "bunx biome format --write || true", | ||
| "dev": "bun run --watch src/index.ts", | ||
| "build": "bun run lint && bun run format && bun build src/index.ts --outdir=build --target=bun --minify && bun run sentry:sourcemaps", | ||
| "start": "bun run build/index.js", | ||
| "sentry:sourcemaps": "sentry-cli sourcemaps inject --org womb0comb0 --project product-decoder-backend ./build && sentry-cli sourcemaps upload --org womb0comb0 --project product-decoder-backend ./build" | ||
| }, | ||
| "dependencies": { | ||
| "@packages/db": "workspace:*", | ||
| "@elysiajs/bearer": "^1.3.0", | ||
| "@elysiajs/cors": "^1.3.3", | ||
| "@elysiajs/jwt": "^1.3.1", | ||
| "@elysiajs/opentelemetry": "^1.3.0", | ||
| "@elysiajs/server-timing": "^1.3.0", | ||
| "@elysiajs/swagger": "^1.3.0", | ||
| "@opentelemetry/resources": "^2.0.1", | ||
| "@sentry/cli": "^2.50.2", | ||
| "@types/bun": "^1.2.20", | ||
| "@types/jsonwebtoken": "^9.0.10", | ||
| "ajv": "^8.17.1", | ||
| "ajv-formats": "^3.0.1", | ||
| "cryptr": "^6.3.0", | ||
| "dayjs": "^1.11.13", | ||
| "elysia": "latest", | ||
| "elysia-ip": "^1.0.10", | ||
| "elysia-rate-limit": "^4.4.0", | ||
| "elysiajs-helmet": "^1.0.2", | ||
| "logixlysia": "^5.1.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@biomejs/biome": "2.1.1", | ||
| "bun-types": "latest", | ||
| "prisma": "^6.11.1" | ||
| } | ||
| } | ||
| { ...same JSON as above... } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| { | ||
| "name": "@apps/backend", | ||
| "private": true, | ||
| "type": "module", | ||
| "scripts": { | ||
| "lint": "bunx biome lint --write || true", | ||
| "check": "bunx biome check --write || true", | ||
| "format": "bunx biome format --write || true", | ||
| "dev": "bun --watch src/index.ts", | ||
| "build": "bun run lint && bun run format && bun build src/index.ts --outdir=build --target=bun --minify && bun run sentry:sourcemaps", | ||
| "start": "bun run build/index.js", | ||
| "sentry:sourcemaps": "sentry-cli sourcemaps inject --org womb0comb0 --project product-decoder-backend ./build && sentry-cli sourcemaps upload --org womb0comb0 --project product-decoder-backend ./build" | ||
| }, | ||
| "dependencies": { | ||
| "@packages/db": "workspace:*", | ||
| "@elysiajs/bearer": "^1.3.0", | ||
| "@elysiajs/cors": "^1.3.3", | ||
| "@elysiajs/jwt": "^1.3.1", | ||
| "@elysiajs/opentelemetry": "^1.3.0", | ||
| "@elysiajs/server-timing": "^1.3.0", | ||
| "@elysiajs/swagger": "^1.3.0", | ||
| "@opentelemetry/resources": "^2.0.1", | ||
| "@sentry/cli": "^2.50.2", | ||
| "@types/bun": "^1.2.20", | ||
| "@types/jsonwebtoken": "^9.0.10", | ||
| "ajv": "^8.17.1", | ||
| "ajv-formats": "^3.0.1", | ||
| "cryptr": "^6.3.0", | ||
| "dayjs": "^1.11.13", | ||
| "elysia": "latest", | ||
| "elysia-ip": "^1.0.10", | ||
| "elysia-rate-limit": "^4.4.0", | ||
| "elysiajs-helmet": "^1.0.2", | ||
| "logixlysia": "^5.1.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@biomejs/biome": "2.1.1", | ||
| "bun-types": "latest", | ||
| "prisma": "^6.11.1" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| { | ||
| "name": "@apps/backend", | ||
| "private": true, | ||
| "type": "module", | ||
| "scripts": { | ||
| "lint": "bunx biome lint --write || true", | ||
| "check": "bunx biome check --write || true", | ||
| "format": "bunx biome format --write || true", | ||
| "dev": "bun --watch src/index.ts", | ||
| "build": "tsc", | ||
| "start": "bun run build/index.js", | ||
| "sentry:sourcemaps": "sentry-cli sourcemaps inject --org womb0comb0 --project product-decoder-backend ./build && sentry-cli sourcemaps upload --org womb0comb0 --project | ||
| product-decoder-backend ./build" | ||
| }, | ||
| "dependencies": { | ||
| "@packages/db": "workspace:*", | ||
| "@elysiajs/bearer": "^1.3.0", | ||
| "@elysiajs/cors": "^1.3.3", | ||
| "@elysiajs/jwt": "^1.3.1", | ||
| "@elysiajs/opentelemetry": "^1.3.0", | ||
| "@elysiajs/server-timing": "^1.3.0", | ||
| "@elysiajs/swagger": "^1.3.0", | ||
| "@opentelemetry/resources": "^2.0.1", | ||
| "@sentry/cli": "^2.50.2", | ||
| "@types/bun": "^1.2.20", | ||
| "@types/jsonwebtoken": "^9.0.10", | ||
| "ajv": "^8.17.1", | ||
| "ajv-formats": "^3.0.1", | ||
| "cryptr": "^6.3.0", | ||
| "dayjs": "^1.11.13", | ||
| "elysia": "latest", | ||
| "elysia-ip": "^1.0.10", | ||
| "elysia-rate-limit": "^4.4.0", | ||
| "elysiajs-helmet": "^1.0.2", | ||
| "logixlysia": "^5.1.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@biomejs/biome": "2.1.1", | ||
| "bun-types": "latest", | ||
| "prisma": "^6.11.1" | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
|
||
| ø |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| { | ||
| "name": "@apps/backend", | ||
| "private": true, | ||
| "type": "module", | ||
| "scripts": { | ||
| "lint": "bunx biome lint --write || true", | ||
| "check": "bunx biome check --write || true", | ||
| "format": "bunx biome format --write || true", | ||
| "dev": "bun --watch src/index.ts", | ||
| "build": "bun run lint && bun run format && bun build src/index.ts --outdir=build --target=bun --minify && bun run sentry:sourcemaps", | ||
| "start": "bun run build/index.js", | ||
| "sentry:sourcemaps": "sentry-cli sourcemaps inject --org womb0comb0 --project product-decoder-backend ./build && sentry-cli sourcemaps upload --org womb0comb0 --project | ||
| product-decoder-backend ./build" | ||
| }, | ||
| "dependencies": { | ||
| "@packages/db": "workspace:*", | ||
| "@elysiajs/bearer": "^1.3.0", | ||
| "@elysiajs/cors": "^1.3.3", | ||
| "@elysiajs/jwt": "^1.3.1", | ||
| "@elysiajs/opentelemetry": "^1.3.0", | ||
| "@elysiajs/server-timing": "^1.3.0", | ||
| "@elysiajs/swagger": "^1.3.0", | ||
| "@opentelemetry/resources": "^2.0.1", | ||
| "@sentry/cli": "^2.50.2", | ||
| "@types/bun": "^1.2.20", | ||
| "@types/jsonwebtoken": "^9.0.10", | ||
| "ajv": "^8.17.1", | ||
| "ajv-formats": "^3.0.1", | ||
| "cryptr": "^6.3.0", | ||
| "dayjs": "^1.11.13", | ||
| "elysia": "latest", | ||
| "elysia-ip": "^1.0.10", | ||
| "elysia-rate-limit": "^4.4.0", | ||
| "elysiajs-helmet": "^1.0.2", | ||
| "logixlysia": "^5.1.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@biomejs/biome": "2.1.1", | ||
| "bun-types": "latest", | ||
| "prisma": "^6.11.1" | ||
| } | ||
| } | ||
| ' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| import path from 'node:path' | ||
| export const BACKEND_ROOT = path.resolve(process.cwd()) | ||
| export const UPLOAD_DIR = path.join(BACKEND_ROOT, 'uploads') |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,33 +1,16 @@ | ||
| import { cors } from '@elysiajs/cors'; | ||
| import { serverTiming } from '@elysiajs/server-timing'; | ||
| import { swagger } from '@elysiajs/swagger'; | ||
| import { Elysia } from 'elysia'; | ||
| import env from '#helpers/env'; | ||
| import authRoutes from '#modules/auth/routes'; | ||
| import meRoutes from '#modules/me/routes'; | ||
| import userRoutes from '#modules/user/routes'; | ||
| import { Elysia } from 'elysia' | ||
| import { cors } from '@elysiajs/cors' | ||
| import { staticPlugin } from '@elysiajs/static' | ||
| import { UPLOAD_DIR } from './config/paths' | ||
| import { uploadRoutes } from './routes/upload' | ||
| import { filesRoutes } from './routes/files' | ||
|
|
||
| console.time('⌛ Startup Time'); | ||
|
|
||
| new Elysia() | ||
| .use(swagger()) | ||
| .use(serverTiming()) | ||
| const app = new Elysia() | ||
| .use(cors()) | ||
| .group('/api', (app) => | ||
| app | ||
| .use(userRoutes) | ||
| .use(authRoutes) | ||
| .use(meRoutes) | ||
| .onError(({ error, ...ctx }) => { | ||
| console.log({ ctx }); | ||
| }), | ||
| ) | ||
| .listen(env.SERVER_PORT, (server) => { | ||
| console.timeEnd('⌛ Startup Time'); | ||
| console.log(`🌱 NODE_ENV: ${env.NODE_ENV || 'development'}`); | ||
| console.log(`🍙 Bun Version: ${Bun.version}`); | ||
| console.log(`🦊 Elysia.js Version: ${require('elysia/package.json').version}`); | ||
| console.log(`🗃️ Prisma Version: ${require('@prisma/client/package.json').version}`); | ||
| console.log(`🚀 Server is running at ${server.url}`); | ||
| console.log('--------------------------------------------------'); | ||
| }); | ||
| .use(staticPlugin({ assets: UPLOAD_DIR, prefix: '/uploads' })) | ||
| .use(filesRoutes) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| .use(uploadRoutes) | ||
| .get('/health', () => ({ ok: true })) | ||
| .listen(process.env.SERVER_PORT ? Number(process.env.SERVER_PORT) : 3001) | ||
|
|
||
| console.log(`Backend listening on http://localhost:${app.server?.port}`) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| import Elysia from 'elysia' | ||
| import path from 'node:path' | ||
| import fs from 'node:fs' | ||
| import { UPLOAD_DIR } from '../config/paths' | ||
|
|
||
| export const filesRoutes = new Elysia() | ||
| .get('/uploads/:name', ({ params, set }) => { | ||
| const filePath = path.join(UPLOAD_DIR, params.name) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| if (!fs.existsSync(filePath)) { | ||
| set.status = 404 | ||
| return 'Not Found' | ||
| } | ||
|
Comment on lines
+9
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using the synchronous if (await Bun.file(filePath).exists()) {
return new Response(Bun.file(filePath));
}
set.status = 404;
return 'Not Found'; |
||
| return new Response(Bun.file(filePath)) | ||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| import Elysia, { t } from 'elysia' | ||
| import { randomUUID } from 'node:crypto' | ||
| import path from 'node:path' | ||
| import fs from 'node:fs/promises' | ||
|
|
||
| import { UPLOAD_DIR } from '../config/paths' | ||
|
|
||
| async function ensureDir(p: string) { | ||
| await fs.mkdir(p, { recursive: true }) | ||
| } | ||
|
|
||
| export const uploadRoutes = new Elysia({ prefix: '/api' }) | ||
| .post( | ||
| '/upload', | ||
| async ({ body, request, set }) => { | ||
| const file = body.image; | ||
| if (!file) { | ||
| set.status = 400 | ||
| return { error: 'No file field "image" found.' } | ||
| } | ||
|
|
||
| if (!file.type?.startsWith('image/')) { | ||
| set.status = 415 | ||
| return { error: 'Only image uploads are allowed.' } | ||
| } | ||
|
|
||
| const ext = file.name?.split('.').pop() || 'bin' | ||
| const id = randomUUID() | ||
| const filename = `${id}.${ext}` | ||
|
|
||
| await ensureDir(UPLOAD_DIR) | ||
| const filepath = path.join(UPLOAD_DIR, filename) | ||
| const arrayBuf = await file.arrayBuffer() | ||
| await Bun.write(filepath, arrayBuf) | ||
|
|
||
| const origin = `${request.headers.get('x-forwarded-proto') || 'http'}://${request.headers.get('host')}` | ||
| const url = `${origin}/uploads/${filename}` | ||
|
|
||
| return { | ||
| id, | ||
| name: file.name, | ||
| type: file.type, | ||
| size: file.size, | ||
| url | ||
| } | ||
| }, | ||
| { | ||
| body: t.Object({ | ||
| image: t.File({ maxSize: 10 * 1024 * 1024 }) // 10MB | ||
| }), | ||
| detail: { tags: ['upload'] } | ||
| } | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| export { auth as middleware } from "@/lib/auth"; | ||
|
|
||
| export const config = { | ||
| matcher: ["/dashboard/:path*"], // protect dashboard | ||
| }; |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,34 @@ | ||
| import ImageUploader from "../../components/ImageUploader"; | ||
| import Link from "next/link"; | ||
|
|
||
| export default function DashboardPage() { | ||
| return ( | ||
| <div className="flex flex-col items-center gap-1"> | ||
| Dashboard index page | ||
| <pre className="bg-card text-card-foreground rounded-md border p-1"> | ||
| app/dashboard/page.tsx | ||
| </pre> | ||
| </div> | ||
| <main className="min-h-screen bg-[#fff7ea]"> | ||
| {/* Top bar matching Figma */} | ||
| <header className="flex items-center justify-between px-8 py-6"> | ||
| <div className="text-[34px] leading-none font-extrabold text-[#5d63e6]"> | ||
| <div>Product</div> | ||
| <div>Decoder</div> | ||
| </div> | ||
|
|
||
| <nav className="flex items-center gap-10 text-[20px]"> | ||
| <Link href="/dashboard" className="text-[#e27d55] font-semibold">Image upload</Link> | ||
| <Link href="/saved" className="font-semibold text-black">Saved searches</Link> | ||
| <Link href="/" className="font-semibold text-black">Home</Link> | ||
| </nav> | ||
|
|
||
| <div className="flex items-center gap-4"> | ||
| <button className="px-5 py-2 rounded-xl bg-[#f8c83b] shadow text-black font-semibold">Log Out</button> | ||
| <div className="w-12 h-12 rounded-full bg-[#f1e7ff] flex items-center justify-center"> | ||
| <UserIcon className="w-6 h-6" /> | ||
| </div> | ||
| </div> | ||
| </header> | ||
|
|
||
| {/* Big blue panel with dashed drop zone */} | ||
| <section className="mt-4"> | ||
| <ImageUploader /> | ||
| </section> | ||
| </main> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This backup file, along with
package.jsonNandpackage.jsonY, appears to be a temporary file that was accidentally committed. These files should not be part of the repository as they add unnecessary clutter. Please remove them and consider adding a pattern like*.bakto your.gitignorefile to prevent this in the future.