sdfsd
This commit is contained in:
@@ -1 +0,0 @@
|
||||
module.exports = { root: true, env: { node: true }, extends: ['eslint:recommended'] };
|
||||
3
api/.gitignore
vendored
3
api/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
node_modules
|
||||
.next
|
||||
styles/tailwind.build.css
|
||||
@@ -1,21 +0,0 @@
|
||||
FROM node:20-alpine AS deps
|
||||
WORKDIR /app
|
||||
COPY package.json .
|
||||
RUN npm install
|
||||
|
||||
FROM node:20-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
RUN npx prisma generate && npm run build
|
||||
|
||||
FROM node:20-alpine AS runner
|
||||
RUN apk add --no-cache openssl
|
||||
ENV NODE_ENV=production
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/package.json ./package.json
|
||||
COPY --from=builder /app/prisma ./prisma
|
||||
EXPOSE 4000
|
||||
CMD ["node", "dist/src/index.js"]
|
||||
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"name": "ci-electrical-api",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "ts-node-dev --respawn --transpile-only src/index.ts",
|
||||
"build": "tsc -p tsconfig.json",
|
||||
"start": "node dist/index.js",
|
||||
"lint": "eslint .",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"seed": "node --loader ts-node/esm prisma/seed.ts",
|
||||
"prisma:generate": "prisma generate",
|
||||
"prisma:migrate": "prisma migrate dev"
|
||||
},
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.19.2",
|
||||
"zod": "3.23.8",
|
||||
"@prisma/client": "5.17.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/express": "^4.17.21",
|
||||
"eslint": "^8.57.0",
|
||||
"typescript": "^5.5.4",
|
||||
"ts-node": "^10.9.2",
|
||||
"ts-node-dev": "^2.0.0",
|
||||
"prisma": "5.17.0"
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
binaryTargets = ["native", "linux-musl-openssl-3.0.x"]
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
model Listing {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
slug String @unique
|
||||
image String?
|
||||
summary String
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model Testimonial {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
area String
|
||||
text String
|
||||
rating Int @default(5)
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
await prisma.listing.upsert({
|
||||
where: { slug: 'retail-lighting-retrofit-south-side' },
|
||||
update: {},
|
||||
create: {
|
||||
title: 'Retail Lighting Retrofit — South Side',
|
||||
slug: 'retail-lighting-retrofit-south-side',
|
||||
image: '/images/project-1.jpg',
|
||||
summary: 'LED conversion for 5,000 sq ft retail space; 35% energy savings.'
|
||||
}
|
||||
});
|
||||
await prisma.listing.upsert({
|
||||
where: { slug: 'panel-upgrade-ocean-drive' },
|
||||
update: {},
|
||||
create: {
|
||||
title: 'Residential Panel Upgrade — Ocean Drive',
|
||||
slug: 'panel-upgrade-ocean-drive',
|
||||
image: '/images/project-2.jpg',
|
||||
summary: '100A → 200A service upgrade with AFCI breakers and EV-ready outlet.'
|
||||
}
|
||||
});
|
||||
await prisma.listing.upsert({
|
||||
where: { slug: 'office-buildout-downtown' },
|
||||
update: {},
|
||||
create: {
|
||||
title: 'Office Build-Out — Downtown',
|
||||
slug: 'office-buildout-downtown',
|
||||
image: '/images/project-3.jpg',
|
||||
summary: 'Complete tenant build-out: power distribution, LED lighting, data wiring.'
|
||||
}
|
||||
});
|
||||
|
||||
await prisma.testimonial.createMany({
|
||||
data: [
|
||||
{ name: 'Maria S.', area: 'Ocean Drive', text: 'Panel upgrade done fast. No more tripping breakers!', rating: 5 },
|
||||
{ name: 'David R.', area: 'Downtown', text: 'Office build-out finished on time. Great team.', rating: 5 },
|
||||
{ name: 'Jennifer L.', area: 'Flour Bluff', text: 'Emergency repair on Sunday. Reliable service.', rating: 5 }
|
||||
],
|
||||
skipDuplicates: true
|
||||
});
|
||||
|
||||
console.log('Seed complete');
|
||||
}
|
||||
|
||||
main().finally(() => prisma.$disconnect());
|
||||
@@ -1,5 +0,0 @@
|
||||
import 'dotenv/config';
|
||||
export const env = {
|
||||
PORT: Number(process.env.PORT || 4000),
|
||||
DATABASE_URL: process.env.DATABASE_URL || 'postgresql://postgres:postgres@localhost:5432/cielectrical?schema=public'
|
||||
};
|
||||
@@ -1,24 +0,0 @@
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
import { env } from './env.js';
|
||||
import listings from './routes/listings.js';
|
||||
import { prisma } from './prisma.js';
|
||||
|
||||
const app = express();
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
|
||||
app.get('/health', async (_req, res) => {
|
||||
try {
|
||||
await prisma.$queryRaw`SELECT 1`;
|
||||
res.json({ ok: true });
|
||||
} catch (e) {
|
||||
res.status(500).json({ ok: false });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/listings', listings);
|
||||
|
||||
app.listen(env.PORT, () => {
|
||||
console.log(`API on :${env.PORT}`);
|
||||
});
|
||||
@@ -1,2 +0,0 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
export const prisma = new PrismaClient();
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import { prisma } from '../prisma.js';
|
||||
const router = Router();
|
||||
|
||||
router.get('/', async (_req, res) => {
|
||||
const listings = await prisma.listing.findMany({ orderBy: { createdAt: 'desc' }, take: 10 });
|
||||
res.json(listings);
|
||||
});
|
||||
|
||||
export default router;
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"lib": [
|
||||
"ES2022"
|
||||
],
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"outDir": "dist",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"include": [
|
||||
"src",
|
||||
"prisma/**/*.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,53 +1,16 @@
|
||||
version: "3.9"
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
|
||||
POSTGRES_DB: ${POSTGRES_DB:-cielectrical}
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- db_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-cielectrical}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
api:
|
||||
build: ./api
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@db:5432/${POSTGRES_DB:-cielectrical}?schema=public
|
||||
PORT: 4000
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "4000:4000"
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "node", "-e", "fetch('http://localhost:4000/health').then(()=>process.exit(0)).catch(()=>process.exit(1))"]
|
||||
interval: 15s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
web:
|
||||
cielectrical-web:
|
||||
build: ./web
|
||||
container_name: cielectrical-web
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
NEXT_TELEMETRY_DISABLED: "1"
|
||||
API_BASE_URL: http://api:4000
|
||||
NEXT_PUBLIC_SITE_URL: http://localhost:3000
|
||||
depends_on:
|
||||
api:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "3000:3000"
|
||||
restart: unless-stopped
|
||||
NEXT_PUBLIC_SITE_URL: https://ci-electrical.com
|
||||
# API_BASE_URL wurde entfernt, da das Backend wegfällt
|
||||
networks:
|
||||
- bizmatch
|
||||
|
||||
volumes:
|
||||
db_data:
|
||||
networks:
|
||||
bizmatch:
|
||||
external: true
|
||||
Reference in New Issue
Block a user