Browse Source

chore: align ai simulation config and prisma schema

ChenYu 4 months ago
parent
commit
dbaed9aed6

+ 38 - 15
backend/prisma/schema.prisma

@@ -21,6 +21,23 @@ enum TemplateTaskStatus {
   FAILED
 }
 
+enum HairTemplateStatus {
+  DRAFT
+  PUBLIC
+}
+
+enum HairTemplateCategory {
+  LONG
+  MEDIUM
+  SHORT
+  DYE
+}
+
+enum HairTemplateSystemFlag {
+  YES
+  NO
+}
+
 enum CustomerExpectContact {
   LINE
   PHONE
@@ -153,21 +170,27 @@ model AiHairSimulationTask {
 }
 
 model HairTemplate {
-  id            BigInt   @id @default(autoincrement()) @db.UnsignedBigInt
-  templateName  String   @map("template_name") @db.VarChar(100)
-  coverUrl      String   @default("") @map("cover_url") @db.VarChar(500)
-  status        String   @db.VarChar(32)
-  category      String   @db.VarChar(32)
-  tags          String   @default("") @db.VarChar(500)
-  description   String?  @db.Text
-  modelUrl      String   @default("") @map("model_url") @db.VarChar(500)
-  clothesUrl    String   @default("") @map("clothes_url") @db.VarChar(500)
-  backgroundUrl String   @default("") @map("background_url") @db.VarChar(500)
-  refHairUrl    String   @default("") @map("ref_hair_url") @db.VarChar(500)
-  createTime    DateTime @default(now()) @map("create_time")
-  updateTime    DateTime @updatedAt @map("update_time")
-  isDeleted     Int      @default(0) @map("is_deleted") @db.UnsignedTinyInt
-
+  id               BigInt                 @id @default(autoincrement()) @db.UnsignedBigInt
+  templateName     String                 @map("template_name") @db.VarChar(100)
+  coverUrl         String                 @default("") @map("cover_url") @db.VarChar(500)
+  status           HairTemplateStatus
+  category         HairTemplateCategory
+  tags             String                 @default("") @db.VarChar(500)
+  description      String?                @db.Text
+  modelUrl         String                 @default("") @map("model_url") @db.VarChar(500)
+  clothesUrl       String                 @default("") @map("clothes_url") @db.VarChar(500)
+  backgroundUrl    String                 @default("") @map("background_url") @db.VarChar(500)
+  refHairUrl       String                 @default("") @map("ref_hair_url") @db.VarChar(500)
+  hairstylistId    BigInt?                @map("hairstylist_id") @db.UnsignedBigInt
+  templateUrl      String                 @default("") @map("template_url") @db.VarChar(500)
+  isSystemTemplate HairTemplateSystemFlag @default(NO) @map("is_system_template")
+  createTime       DateTime               @default(now()) @map("create_time")
+  updateTime       DateTime               @updatedAt @map("update_time")
+  isDeleted        Int                    @default(0) @map("is_deleted") @db.UnsignedTinyInt
+
+  @@index([category, isDeleted], map: "idx_category")
+  @@index([hairstylistId, isDeleted], map: "idx_hairstylist_id")
+  @@index([status, isDeleted], map: "idx_status")
   @@map("hair_template")
 }
 

+ 14 - 0
backend/src/config/app.config.spec.ts

@@ -52,4 +52,18 @@ describe('appConfig storage', () => {
       'https://storage.googleapis.com/aitori-public/style/sample/066c7ba22ea149268444bc2d919d5b97.png',
     );
   });
+
+  it('maps ai simulation config from env', () => {
+    process.env.AI_SIMULATION_BASE_URL = 'http://localhost:8084';
+    process.env.AI_SIMULATION_REFRESH_INTERVAL_MS = '10000';
+    process.env.AI_SIMULATION_HTTP_TIMEOUT_MS = '15000';
+
+    const config = appConfig();
+
+    expect(config.aiSimulation).toEqual({
+      baseUrl: 'http://localhost:8084',
+      refreshIntervalMs: 10000,
+      httpTimeoutMs: 15000,
+    });
+  });
 });

+ 7 - 0
backend/src/config/app.config.ts

@@ -6,6 +6,13 @@ export default () => ({
   port: Number(process.env.PORT ?? 3000),
   appBaseUrl: process.env.APP_BASE_URL ?? 'http://localhost:3000',
   corsOrigin: process.env.CORS_ORIGIN ?? 'http://127.0.0.1:5173',
+  aiSimulation: {
+    baseUrl: process.env.AI_SIMULATION_BASE_URL ?? 'http://localhost:8084',
+    refreshIntervalMs: Number(
+      process.env.AI_SIMULATION_REFRESH_INTERVAL_MS ?? 10000,
+    ),
+    httpTimeoutMs: Number(process.env.AI_SIMULATION_HTTP_TIMEOUT_MS ?? 15000),
+  },
   jwtSecret: process.env.JWT_SECRET ?? 'replace-me',
   jwtExpiresIn: process.env.JWT_EXPIRES_IN ?? '7d',
   databaseUrl:

+ 3 - 0
backend/src/config/env.schema.ts

@@ -5,6 +5,9 @@ export const envSchema = z.object({
   APP_BASE_URL: z.string().default('http://localhost:3000'),
   DATABASE_URL: z.string().default('mysql://root:root@localhost:3306/aitori_backend'),
   REDIS_URL: z.string().default('redis://localhost:6379'),
+  AI_SIMULATION_BASE_URL: z.string().url().default('http://localhost:8084'),
+  AI_SIMULATION_REFRESH_INTERVAL_MS: z.coerce.number().int().positive().default(10000),
+  AI_SIMULATION_HTTP_TIMEOUT_MS: z.coerce.number().int().positive().default(15000),
   JWT_SECRET: z.string().default('replace-me'),
   JWT_EXPIRES_IN: z.string().default('7d'),
   CORS_ORIGIN: z.string().default('http://127.0.0.1:5173'),