Skip to content

Conversation

@ImTotem
Copy link
Collaborator

@ImTotem ImTotem commented Jan 19, 2026

🔍 개요

  • 단체에서 작성한 글 기능 구현

🚀 주요 변경 내용


💬 참고 사항

  • 로컬로 테스트할 수 있는 상태가 아니라서 테스트를 못해봤습니다. (로컬 설정 날라감, 노트북 상태 이상함, intellij 열기만 했는데 cpu, 메모리 90% 찍음)
  • PR 리뷰전에 테스트 해보고 리뷰해주세요.
  • sql 쿼리도 확인해주세요. sql 공부 안해서 자신없음.

✅ Checklist (완료 조건)

  • 코드 스타일 가이드 준수
  • 테스트 코드 포함됨
  • Reviewers / Assignees / Labels 지정 완료
  • 보안 및 민감 정보 검증 (API 키, 환경 변수, 개인정보 등)

* 분실물 게시글 작성자의 단체 정보를 관리하기 위한 organizations 테이블 및 엔티티 추가
* is_council 대신 organization 객체로 단체 정보 제공
@ImTotem ImTotem self-assigned this Jan 19, 2026
Copilot AI review requested due to automatic review settings January 19, 2026 14:27
@ImTotem ImTotem added 기능 새로운 기능을 개발합니다. Team Campus 캠퍼스 팀에서 작업할 이슈입니다 labels Jan 19, 2026
@github-actions
Copy link

Unit Test Results

673 tests   670 ✔️  1m 18s ⏱️
165 suites      3 💤
165 files        0

Results for commit c5802f0.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements organization-authored articles functionality, allowing organizations (like student councils) to post articles and be identified as such. The change introduces a new organizations table to store organization metadata and adds a V2 endpoint for lost item articles that includes organization information.

Changes:

  • Added organizations table to store organization details (name and location) linked to user accounts
  • Created Organization entity and repository for database operations
  • Implemented getLostItemArticleV2 service method that queries organization data
  • Added LostItemArticleResponseV2 DTO with embedded organization information
  • Exposed new V2 endpoint /lost-item/v2/{id} that returns organization details for organizational authors

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
V228__add_organizations_table.sql Database migration creating the organizations table with user_id, name, location, and soft-delete fields
OrganizationRepository.java Repository interface for querying organizations by user ID
Organization.java JPA entity representing organization data
LostItemArticleService.java Service layer enhanced with V2 method that fetches organization info for article authors
LostItemArticleResponseV2.java Response DTO including nested organization details when present
LostItemArticleController.java Controller exposing the new V2 endpoint
LostItemArticleApi.java API documentation for the V2 endpoint

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +8 to +9
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The created_at and updated_at columns should be removed from this migration. Since the Organization entity extends BaseEntity, these timestamp fields are automatically managed by JPA's auditing mechanism. Including them in the SQL migration will cause conflicts with JPA's entity mappings and create duplicate column definitions.

Suggested change
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

Copilot uses AI. Check for mistakes.
private String location;

@NotNull
@Column(name = "is_deleted", nullable = false)
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The is_deleted column definition in the SQL migration uses TINYINT(1) which is the standard for boolean columns in this codebase. However, the corresponding entity field uses Boolean type without the columnDefinition attribute. For consistency with other entities in the codebase (like KoinNotice, Club, ClubQna), add a columnDefinition attribute to ensure proper mapping: @Column(name = "is_deleted", nullable = false, columnDefinition = "TINYINT(1) DEFAULT 0")

Suggested change
@Column(name = "is_deleted", nullable = false)
@Column(name = "is_deleted", nullable = false, columnDefinition = "TINYINT(1) DEFAULT 0")

Copilot uses AI. Check for mistakes.

@NotNull
@Column(name = "is_deleted", nullable = false)
private Boolean isDeleted = false;
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

For consistency with other entities in the codebase that use boolean fields (such as KoinNotice, Club), consider using the static import import static java.lang.Boolean.FALSE; and initializing the field as private Boolean isDeleted = FALSE; instead of false. This follows the established pattern in the project.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,16 @@
-- organizations 테이블 생성 (단체 정보 관리)
CREATE TABLE `organizations` (
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The table creation should include the schema prefix for consistency with other recent migrations in the codebase. Recent migrations (V194, V222, V226) consistently use CREATE TABLE IF NOT EXISTS \koin`.`table_name`pattern. Update the statement to:CREATE TABLE IF NOT EXISTS `koin`.`organizations``

Suggested change
CREATE TABLE `organizations` (
CREATE TABLE IF NOT EXISTS `koin`.`organizations` (

Copilot uses AI. Check for mistakes.
-- organizations 테이블 생성 (단체 정보 관리)
CREATE TABLE `organizations` (
`id` INT NOT NULL AUTO_INCREMENT,
`user_id` INT NOT NULL COMMENT '단체 계정 user_id',
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The user_id column uses INT instead of INT UNSIGNED. Since this column references the users table's id column (which is typically INT UNSIGNED in this codebase), it should match that type for proper foreign key compatibility. Use INT UNSIGNED NOT NULL COMMENT '단체 계정 user_id'

Suggested change
`user_id` INT NOT NULL COMMENT '단체 계정 user_id',
`user_id` INT UNSIGNED NOT NULL COMMENT '단체 계정 user_id',

Copilot uses AI. Check for mistakes.
Comment on lines +148 to +165
public LostItemArticleResponseV2 getLostItemArticleV2(Integer articleId, Integer userId) {
Article article = articleRepository.getById(articleId);
setPrevNextArticle(LOST_ITEM_BOARD_ID, article);

LostItemArticle lostItemArticle = article.getLostItemArticle();
User author = lostItemArticle.getAuthor();

boolean isMine = author != null && Objects.equals(author.getId(), userId);

Organization organization = null;
if (author != null) {
organization = organizationRepository
.findByUserIdAndIsDeletedFalse(author.getId())
.orElse(null);
}

return LostItemArticleResponseV2.of(article, isMine, organization);
}
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The new getLostItemArticleV2 method lacks test coverage. Given that the codebase has test infrastructure in place (as evidenced by LostItemChatRoomInfoServiceTest and fixtures), unit tests should be added to verify the organization lookup behavior, including scenarios where:

  1. An article is authored by a user with an associated organization
  2. An article is authored by a user without an organization (null case)
  3. An article is authored by a deleted/null user

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +18
import lombok.NoArgsConstructor;

@Getter
@Entity
@Table(name = "organizations")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The Organization entity has an is_deleted field but is missing the @Where(clause = "is_deleted=0") annotation that is consistently used across the codebase for soft-delete functionality. This annotation ensures that deleted entities are automatically filtered out from queries by default. For consistency with other entities (like Article, KoinNotice, User, etc.), add this annotation to the class level.

Suggested change
import lombok.NoArgsConstructor;
@Getter
@Entity
@Table(name = "organizations")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Where;
@Getter
@Entity
@Table(name = "organizations")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Where(clause = "is_deleted=0")

Copilot uses AI. Check for mistakes.
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_organizations_user_id` (`user_id`)
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The user_id column references a user but does not include a FOREIGN KEY constraint. Based on the codebase patterns (e.g., V100, V152, V204), columns that reference other tables should include explicit foreign key constraints. Consider adding: CONSTRAINT fk_organizations_user_id FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE or ON DELETE SET NULL depending on the desired behavior when a user is deleted.

Suggested change
UNIQUE KEY `uk_organizations_user_id` (`user_id`)
UNIQUE KEY `uk_organizations_user_id` (`user_id`),
CONSTRAINT `fk_organizations_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,16 @@
-- organizations 테이블 생성 (단체 정보 관리)
CREATE TABLE `organizations` (
`id` INT NOT NULL AUTO_INCREMENT,
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The id column uses INT instead of INT UNSIGNED which is the standard in recent migrations (V140+). For consistency with the codebase and to allow for a larger range of positive IDs, use INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '고유 ID'

Suggested change
`id` INT NOT NULL AUTO_INCREMENT,
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '고유 ID',

Copilot uses AI. Check for mistakes.
return ResponseEntity.ok().body(lostItemArticleService.getLostItemArticle(articleId, userId));
}

@GetMapping("/lost-item/v2/{id}")
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

This method overrides LostItemArticleApi.getLostItemArticleV2; it is advisable to add an Override annotation.

Suggested change
@GetMapping("/lost-item/v2/{id}")
@GetMapping("/lost-item/v2/{id}")
@Override

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Team Campus 캠퍼스 팀에서 작업할 이슈입니다 기능 새로운 기능을 개발합니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[캠퍼스] OOO에서 작성한 글 기능 구현

2 participants