Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/ai/ai.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { QuestionEntity } from './entities/ai.question.entity';
import { AnswerEntity } from './entities/ai.answer.entity';
import { DiaryQuestionEntity } from './entities/ai.diary.question.entity';

@Module({
imports: [
TypeOrmModule.forFeature([
QuestionEntity,
AnswerEntity,
DiaryQuestionEntity,
]),
],
controllers: [],
providers: [],
exports: [TypeOrmModule],
})
export class AiModule {}
23 changes: 23 additions & 0 deletions src/ai/entities/ai-answer.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
} from 'typeorm';

@Entity('Answer')
export class AnswerEntity {
@PrimaryGeneratedColumn({ name: 'answer_id', type: 'int' })
answerId: number;

@Column({ name: 'answer', type: 'text' })
answer: string;

@CreateDateColumn({
name: 'created_at',
type: 'timestamp',
nullable: false,
comment: '생성일',
})
createdAt: Date;
}
31 changes: 31 additions & 0 deletions src/ai/entities/ai-diary.question.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
} from 'typeorm';
Comment on lines +1 to +6

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

AiModule의 엔티티 import 경로와 실제 파일명이 일치하지 않습니다.

제공된 src/ai/ai.module.ts./entities/ai.question.entity, ./entities/ai.answer.entity, ./entities/ai.diary.question.entity를 import하지만 실제 파일명은 하이픈 기반입니다. 이 상태에서는 모듈 해석이 실패합니다. 세 import 경로를 실제 파일명에 맞추고, 이 파일은 ai-diary-question.entity.ts로 변경해 kebab-case 규칙도 충족하세요.

권장 수정
- './entities/ai.question.entity'
+ './entities/ai-question.entity'

- './entities/ai.answer.entity'
+ './entities/ai-answer.entity'

- './entities/ai.diary.question.entity'
+ './entities/ai-diary-question.entity'
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/ai/entities/ai-diary.question.entity.ts` around lines 1 - 6, Update the
imports in AiModule to reference the actual hyphen-based entity filenames for
the question, answer, and diary-question entities, and rename the diary question
entity file to ai-diary-question.entity.ts. Ensure all references use the
renamed kebab-case path.

Sources: Coding guidelines, Path instructions


@Entity('DiaryQuestion')
export class DiaryQuestionEntity {
@PrimaryGeneratedColumn({
name: 'diary_question_id',
type: 'int',
comment: '일기-질문 아이디',
})
diaryQuestionId: number;

@Column({
name: 'is_written',
type: 'boolean',
nullable: false,
default: false,
})
isWritten: boolean;

@CreateDateColumn({
name: 'created_at',
type: 'timestamp',
comment: '생성일자',
})
createdAt: Date;
}
27 changes: 27 additions & 0 deletions src/ai/entities/ai-question.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity('Question')
export class QuestionEntity {
@PrimaryGeneratedColumn({
name: 'question_id',
type: 'int',
comment: '질문ID',
})
questionId: number;

@Column({
name: 'content',
type: 'text',
nullable: false,
comment: '질문내용',
})
content: string;

@Column({
name: 'target_date',
type: 'date',
nullable: false,
comment: '질문 날짜',
})
targetDate: string;
}
Comment on lines +1 to +27

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "## files"
git ls-files 'src/**' | rg '(^src/ai/entities/|answer|diary.*question|question.*entity)' || true

echo "## search relations"
rg -n "`@ManyToOne`|`@OneToOne`|`@JoinColumn`|question_id|answer_id|diary_question|QuestionEntity|AnswerEntity|DiaryQuestionEntity" src/ai src 2>/dev/null || true

Repository: TEAM-DAILOG/BE

Length of output: 2331


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map entity files under src/ai/entities first.
fd -a -t f '.*\.entity\.ts$' src/ai/entities src 2>/dev/null || true

# Show outlines for the most relevant files if they exist.
for f in \
  src/ai/entities/ai.question.entity.ts \
  src/ai/entities/ai.answer.entity.ts \
  src/ai/entities/ai.diary-question.entity.ts \
  src/ai/entities/ai.diary.question.entity.ts \
  src/ai/entities/answer.entity.ts \
  src/ai/entities/diary-question.entity.ts
do
  if [ -f "$f" ]; then
    echo "## outline: $f"
    ast-grep outline "$f" --view expanded || true
  fi
done

Repository: TEAM-DAILOG/BE

Length of output: 1419


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "## entity files"
find src -type f -name '*.entity.ts' | sort | sed -n '1,200p'

echo "## ai entity definitions"
for f in $(find src/ai -type f -name '*.entity.ts' | sort); do
  echo "### $f"
  sed -n '1,220p' "$f" | rg -n "^(import |`@Entity`|export class|  @|  [a-zA-Z0-9_]+:)"
done

echo "## relation decorators involving question/answer/diary"
rg -n "`@ManyToOne`|`@OneToOne`|`@ManyToMany`|`@JoinColumn`|questionId|answerId|diaryQuestion|targetDate" src/ai src 2>/dev/null || true

Repository: TEAM-DAILOG/BE

Length of output: 2256


Question/Answer/DiaryQuestion에 FK 관계를 추가하세요
현재 QuestionEntity, AnswerEntity, DiaryQuestionEntity가 모두 독립 테이블로만 정의돼 있어 질문-답변-일기질문 간 참조 무결성이 보장되지 않습니다. 최종 스키마가 맞다면 이를 연결하는 FK 컬럼과 @ManyToOne/@OneToOne 매핑이 필요합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/ai/entities/ai.question.entity.ts` around lines 1 - 27, QuestionEntity is
still defined as an isolated table, so add the missing foreign-key relationships
that connect Question/Answer/DiaryQuestion with TypeORM relations. Update the
relevant entity classes (QuestionEntity, AnswerEntity, DiaryQuestionEntity) to
include FK columns and matching `@ManyToOne` or `@OneToOne` mappings, using the
existing entity/property names to wire the references so the schema enforces
referential integrity.

Source: Path instructions

42 changes: 42 additions & 0 deletions src/ai/entities/ai-recommend.entitiy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
} from 'typeorm';

@Entity('Recommend')
export class RecommendEntity {
Comment on lines +8 to +9

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## File list\n'
git ls-files | rg '(^src/(ai|diaries)/entities/.*recommend.*\.ts$|typeorm|migration|migrations|data-source|ormconfig|naming-strategy)'

printf '\n## Entity files\n'
for f in src/ai/entities/ai-recommend.entitiy.ts src/diaries/entities/recommend.entity.ts; do
  if [ -f "$f" ]; then
    echo "---- $f"
    cat -n "$f"
  fi
done

printf '\n## Search for table/entity decorators and naming strategy\n'
rg -n "`@Entity`\\(|namingStrategy|snake_case|camelCase|tableName|Recommend|recommend" src . --glob '!node_modules' --glob '!dist' --glob '!build' --glob '!coverage' | sed -n '1,240p'

Repository: TEAM-DAILOG/BE

Length of output: 5731


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## package.json\n'
cat -n package.json

printf '\n## app.module.ts\n'
cat -n src/app.module.ts

printf '\n## AI module files\n'
git ls-files 'src/ai/**' | sed -n '1,200p'

printf '\n## AI module and related imports\n'
rg -n "AiModule|TypeOrmModule.forFeature|entities:" src/ai src/app.module.ts src/**/*.module.ts --glob '!node_modules' --glob '!dist' --glob '!build' | sed -n '1,240p'

Repository: TEAM-DAILOG/BE

Length of output: 5428


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## ai.module.ts\n'
cat -n src/ai/ai.module.ts

printf '\n## diaries.module.ts\n'
cat -n src/diaries/diary.module.ts

printf '\n## search for repository usage of AI recommend entity\n'
rg -n "ai-recommend|RecommendEntity|recommendId|isAdded|categoryId|diaryId" src/ai src/diaries src --glob '!node_modules' --glob '!dist' --glob '!build' | sed -n '1,240p'

Repository: TEAM-DAILOG/BE

Length of output: 3209


🌐 Web query:

TypeORM SnakeNamingStrategy explicit @entity('Recommend') table name case-sensitive quotes explicit table name behavior

💡 Result:

In TypeORM, the Naming Strategy and explicit @Entity declarations interact as follows: Naming Strategy Behavior The Naming Strategy (such as SnakeNamingStrategy) is only applied when a table name is not explicitly provided in the @Entity decorator [1][2]. The tableName(targetName, userSpecifiedName) method receives the userSpecifiedName argument [2]. If userSpecifiedName is provided (e.g., @Entity('my_table')), the naming strategy's logic is bypassed for the table name [1][3]. Explicit Table Name (@Entity) When you use @Entity('Recommend') or @Entity({ name: 'Recommend' }), you are explicitly telling TypeORM to use exactly that string as the table name [4][5][6]. The framework will use this value as-is, overriding any automatic transformation logic provided by a SnakeNamingStrategy [1]. Case-Sensitivity and Quotes TypeORM often wraps table and column names in double quotes (e.g., "Recommend") in generated SQL queries [7][8]. This behavior is driver-dependent (e.g., PostgreSQL and Oracle are case-sensitive when identifiers are quoted) [7][8]. If you encounter issues where the database cannot find your table (e.g., ORA-00942 in Oracle or similar errors in PostgreSQL), it is often because: 1. The database expects table names in a specific case (usually UPPERCASE) when they are quoted [7][8]. 2. The name provided in @Entity does not match the database's internal representation [7]. To fix case-sensitivity/quoting issues: - Verify your database's case-sensitivity policy for identifiers. - Match the casing in @Entity exactly to what the database expects (e.g., use @Entity('RECOMMEND') if your database stores the table as uppercase) [7][8]. - If your database treats unquoted identifiers as case-insensitive but quoted ones as case-sensitive, ensure the name in your decorator matches the expected case precisely [7]. In summary, the SnakeNamingStrategy will not force a lowercase conversion on an explicit name provided in the @Entity decorator; the decorator takes precedence [1][3]. If you need a specific case, you must define it explicitly in the decorator [7][8].

Citations:


테이블명을 하나로 통일하세요.
@Entity('Recommend')@Entity('recommend')SnakeNamingStrategy와 무관하게 서로 다른 테이블로 매핑됩니다. PostgreSQL에서는 quoted identifier가 대소문자를 구분하므로, 현재 상태면 Recommendrecommend가 분리되어 스키마/데이터가 엇갈릴 수 있습니다. 기존 엔티티를 재사용하거나 AI 전용 테이블명으로 분리하고 마이그레이션을 추가해 주세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/ai/entities/ai-recommend.entitiy.ts` around lines 8 - 9, Unify the table
mapping used by RecommendEntity with the existing Recommend entity, choosing one
consistent table name rather than mixing “Recommend” and “recommend”. Reuse the
existing entity mapping where appropriate, or intentionally use a separate
AI-specific table name and add the corresponding migration so schema and data
remain aligned.

@PrimaryGeneratedColumn({
name: 'recommend_id',
type: 'int',
comment: '추천ID',
})
recommendId: number;

@Column({
name: 'title',
type: 'varchar',
length: 500,
nullable: false,
comment: '추천 일정 제목',
})
title: string;

@Column({
name: 'is_added',
type: 'boolean',
nullable: false,
default: false,
comment: '일정 추가 여부',
})
isAdded: boolean;

@CreateDateColumn({
name: 'created_at',
type: 'timestamp',
nullable: false,
comment: '생성일자',
})
createdAt: Date;
}
2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AlarmsModule } from './alarms/alarms.module';
import { ScheduleModule } from './schedules/schedule.module';
import { UserModule } from './users/user.module';
import { DiariesModule } from './diaries/diary.module';
import { AiModule } from './ai/ai.module';

@Module({
imports: [
Expand All @@ -31,6 +32,7 @@ import { DiariesModule } from './diaries/diary.module';
ScheduleModule,
UserModule,
DiariesModule,
AiModule,
],
controllers: [AppController],
providers: [],
Expand Down