Spaces:
Running
Running
| import "reflect-metadata"; | |
| import express from "express"; | |
| import cors from "cors"; | |
| import dotenv from "dotenv"; | |
| import swaggerJsdoc from "swagger-jsdoc"; | |
| import swaggerUi from "swagger-ui-express"; | |
| import { AppDataSource } from "./utils/dataSource"; | |
| import authRoute from "./routes/auth"; | |
| import uploadRoute from "./routes/upload"; | |
| import suggestRoute from "./routes/suggest"; | |
| import wardrobeRoute from "./routes/wardrobe"; | |
| import profileRoute from "./routes/profile"; | |
| import avatarRoute from "./routes/avatar"; | |
| import chatRoute from "./routes/chat"; | |
| dotenv.config(); | |
| const app = express(); | |
| app.use(cors()); | |
| app.use(express.json({ limit: "10mb" })); | |
| // Root endpoint with milestone information | |
| app.get("/", (req, res) => { | |
| res.json({ | |
| name: "StyleGPT Milestone 2", | |
| version: "1.0.0", | |
| description: "Visual Wardrobe Tagging & AI-Powered Outfit Suggestions", | |
| milestone: 2, | |
| features: [ | |
| "User Authentication (JWT-based)", | |
| "Visual Wardrobe Management", | |
| "AI-Powered Image Classification (Fashion-CLIP)", | |
| "Smart Outfit Suggestions", | |
| "User Profile Management" | |
| ], | |
| endpoints: { | |
| root: "/", | |
| docs: "/docs", | |
| health: "/health", | |
| api: { | |
| auth: "/api/auth", | |
| profile: "/api/profile", | |
| upload: "/api/upload", | |
| suggest: "/api/suggest", | |
| chat: "/api/chat", | |
| wardrobe: "/api/wardrobe", | |
| avatar: "/api/avatar" | |
| } | |
| }, | |
| technologies: [ | |
| "Node.js", | |
| "TypeScript", | |
| "Express.js", | |
| "PostgreSQL", | |
| "TypeORM", | |
| "Hugging Face Fashion-CLIP", | |
| "JWT Authentication" | |
| ] | |
| }); | |
| }); | |
| // Swagger/OpenAPI configuration | |
| const swaggerOptions: swaggerJsdoc.Options = { | |
| definition: { | |
| openapi: "3.0.0", | |
| info: { | |
| title: "StyleGPT Milestone 2 API", | |
| version: "1.0.0", | |
| description: "API documentation for StyleGPT Milestone 2 - Visual Wardrobe Tagging & AI-Powered Outfit Suggestions", | |
| contact: { | |
| name: "StyleGPT", | |
| url: "https://huggingface.co/spaces/nexusbert/StyleGPT-milestone2" | |
| } | |
| }, | |
| servers: [ | |
| { | |
| url: process.env.API_URL || `http://localhost:${process.env.PORT || 7860}`, | |
| description: "API Server" | |
| } | |
| ], | |
| components: { | |
| securitySchemes: { | |
| bearerAuth: { | |
| type: "http", | |
| scheme: "bearer", | |
| bearerFormat: "JWT" | |
| } | |
| }, | |
| schemas: { | |
| User: { | |
| type: "object", | |
| properties: { | |
| id: { type: "integer" }, | |
| name: { type: "string" }, | |
| email: { type: "string", format: "email" }, | |
| profilePicture: { type: "string", format: "uri", description: "Avatar render URL or base64 image" }, | |
| readyPlayerMeAvatarId: { type: "string", description: "Ready Player Me avatar ID" }, | |
| createdAt: { type: "string", format: "date-time" } | |
| } | |
| }, | |
| WardrobeItem: { | |
| type: "object", | |
| properties: { | |
| id: { type: "integer" }, | |
| imageUrl: { type: "string", format: "uri" }, | |
| category: { | |
| type: "string", | |
| description: "Classification: shirt, pants, dress, jacket, shoes, sneakers, boots, watch, glasses, bag, hat, jewelry, accessories, etc." | |
| }, | |
| style: { | |
| type: "string", | |
| enum: ["formal", "casual", "streetwear", "sportswear"], | |
| description: "Style classification" | |
| }, | |
| userId: { type: "integer" }, | |
| createdAt: { type: "string", format: "date-time" } | |
| } | |
| }, | |
| RegisterRequest: { | |
| type: "object", | |
| required: ["name", "email", "password"], | |
| properties: { | |
| name: { type: "string" }, | |
| email: { type: "string", format: "email" }, | |
| password: { type: "string", minLength: 6 } | |
| } | |
| }, | |
| LoginRequest: { | |
| type: "object", | |
| required: ["email", "password"], | |
| properties: { | |
| email: { type: "string", format: "email" }, | |
| password: { type: "string" } | |
| } | |
| }, | |
| AuthResponse: { | |
| type: "object", | |
| properties: { | |
| success: { type: "boolean" }, | |
| user: { $ref: "#/components/schemas/User" }, | |
| token: { type: "string" }, | |
| error: { type: "string" } | |
| } | |
| }, | |
| UploadRequest: { | |
| type: "object", | |
| required: ["image"], | |
| properties: { | |
| image: { | |
| type: "string", | |
| format: "binary", | |
| description: "Image file (JPEG, PNG, etc.)" | |
| } | |
| } | |
| }, | |
| SuggestRequest: { | |
| type: "object", | |
| required: ["message"], | |
| properties: { | |
| message: { type: "string" }, | |
| session_id: { type: "string" } | |
| } | |
| } | |
| } | |
| }, | |
| tags: [ | |
| { name: "Authentication", description: "User registration and login" }, | |
| { name: "Profile", description: "User profile management" }, | |
| { name: "Upload", description: "Wardrobe item upload and classification" }, | |
| { name: "Suggest", description: "AI-powered outfit suggestions with wardrobe" }, | |
| { name: "Chat", description: "Fashion chat without wardrobe" }, | |
| { name: "Avatar", description: "Ready Player Me avatar management" }, | |
| { name: "Health", description: "Health check endpoints" } | |
| ] | |
| }, | |
| apis: ["./src/routes/*.ts", "./src/index.ts"] | |
| }; | |
| const swaggerSpec = swaggerJsdoc(swaggerOptions); | |
| // Swagger UI endpoint | |
| app.use("/docs", swaggerUi.serve, swaggerUi.setup(swaggerSpec, { | |
| customCss: ".swagger-ui .topbar { display: none }", | |
| customSiteTitle: "StyleGPT Milestone 2 API Docs" | |
| })); | |
| // Swagger JSON endpoint | |
| app.get("/docs.json", (req, res) => { | |
| res.setHeader("Content-Type", "application/json"); | |
| res.send(swaggerSpec); | |
| }); | |
| // Health check endpoint | |
| /** | |
| * @openapi | |
| * /health: | |
| * get: | |
| * summary: Health check endpoint | |
| * tags: [Health] | |
| * responses: | |
| * 200: | |
| * description: Service is healthy | |
| * content: | |
| * application/json: | |
| * schema: | |
| * type: object | |
| * properties: | |
| * status: | |
| * type: string | |
| * example: healthy | |
| * database: | |
| * type: boolean | |
| * example: true | |
| */ | |
| app.get("/health", (req, res) => { | |
| res.json({ status: "healthy", database: AppDataSource.isInitialized }); | |
| }); | |
| app.use("/api/auth", authRoute); | |
| app.use("/api/profile", profileRoute); | |
| app.use("/api/upload", uploadRoute); | |
| app.use("/api/suggest", suggestRoute); | |
| app.use("/api/wardrobe", wardrobeRoute); | |
| app.use("/api/avatar", avatarRoute); | |
| app.use("/api/chat", chatRoute); | |
| const PORT = process.env.PORT || 7860; | |
| AppDataSource.initialize() | |
| .then(() => { | |
| console.log("✅ Database connected"); | |
| app.listen(PORT, () => console.log(`🧥 StyleGPT running on port ${PORT}`)); | |
| }) | |
| .catch((error) => console.error("❌ DB connection failed:", error)); | |