first commit

This commit is contained in:
2026-03-06 13:31:28 +08:00
commit e125321cae
42 changed files with 17645 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});

View File

@@ -0,0 +1,12 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}

11
backend/src/app.module.ts Normal file
View File

@@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { LeadsModule } from './leads/leads.module';
@Module({
imports: [LeadsModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

View File

@@ -0,0 +1,8 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}

View File

@@ -0,0 +1,10 @@
import { IsString, IsNotEmpty } from 'class-validator';
export class CreateFeedbackDto {
@IsString()
@IsNotEmpty()
status: string;
@IsString()
reason?: string;
}

View File

@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { LeadsController } from './leads.controller';
describe('LeadsController', () => {
let controller: LeadsController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [LeadsController],
}).compile();
controller = module.get<LeadsController>(LeadsController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@@ -0,0 +1,21 @@
import { CreateFeedbackDto } from './dto/feedback.dto';
import { Controller, Post, Body, Param, Get } from '@nestjs/common';
import { LeadsService } from './leads.service';
@Controller('leads')
export class LeadsController {
constructor(private readonly leadsService: LeadsService) { }
@Post(':id/feedback')
async updateLeadFeedback(
@Param('id') id: string,
@Body() feedbackDto: CreateFeedbackDto
) {
return this.leadsService.saveFeedback(id, feedbackDto);
}
@Get()
findAll() {
return this.leadsService.getAllLeads();
}
}

View File

@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { LeadsController } from './leads.controller';
import { LeadsService } from './leads.service';
@Module({
controllers: [LeadsController],
providers: [LeadsService]
})
export class LeadsModule {}

View File

@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { LeadsService } from './leads.service';
describe('LeadsService', () => {
let service: LeadsService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [LeadsService],
}).compile();
service = module.get<LeadsService>(LeadsService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@@ -0,0 +1,38 @@
import { Injectable } from '@nestjs/common';
import axios from 'axios';
@Injectable()
export class LeadsService {
async saveFeedback(leadId: string, feedback: { status: string; reason?: string }) {
console.log(`Received ${feedback.status} for lead ${leadId}: ${feedback.reason}`);
// Future: Logic to call Python backend goes here
return await this.sendFeedbackToPython(leadId, feedback);
}
private readonly PYTHON_API = 'http://localhost:8000';
async getAllLeads() {
const response = await axios.get(`${this.PYTHON_API}/leads`);
return response.data;
}
async sendFeedbackToPython(id: string, data: any) {
try {
const response = await axios.post(
`${this.PYTHON_API}/leads/${id}/feedback`,
data,
{
headers: {
'Content-Type': 'application/json',
},
}
);
return response.data;
} catch (error) {
console.error("Axios Error Details:", error.response?.data);
throw error;
}
}
}

9
backend/src/main.ts Normal file
View File

@@ -0,0 +1,9 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();