docs: add DB table creation rules and guidelines

- Introduced essential rules for creating database tables, emphasizing the use of `VARCHAR(500)` for all business columns and the inclusion of five mandatory columns.
- Specified the requirement for registering three metadata tables: `table_labels`, `table_type_columns`, and `column_labels`.
- Outlined prohibited practices, including the direct use of certain database types and the necessity of including the `ON CONFLICT` clause for handling duplicates.

Made-with: Cursor
This commit is contained in:
kjs 2026-03-11 15:04:05 +09:00
parent fa97b361ed
commit 5fb1f705dc
4 changed files with 34 additions and 3 deletions

View File

@ -1510,3 +1510,34 @@ const query = `
**company_code = "*"는 공통 데이터가 아닌 최고 관리자 전용 데이터입니다!**
---
## DB 테이블 생성 필수 규칙
**상세 가이드**: [table-type-sql-guide.mdc](.cursor/rules/table-type-sql-guide.mdc)
### 핵심 원칙 (절대 위반 금지)
1. **모든 비즈니스 컬럼은 `VARCHAR(500)`**: NUMERIC, INTEGER, SERIAL, TEXT 등 DB 타입 직접 지정 금지
2. **기본 5개 컬럼 자동 포함** (모든 테이블 필수):
```sql
"id" varchar(500) PRIMARY KEY DEFAULT gen_random_uuid()::text,
"created_date" timestamp DEFAULT now(),
"updated_date" timestamp DEFAULT now(),
"writer" varchar(500) DEFAULT NULL,
"company_code" varchar(500)
```
3. **3개 메타데이터 테이블 등록 필수**:
- `table_labels`: 테이블 라벨/설명
- `table_type_columns`: 컬럼 input_type, detail_settings (company_code = '*')
- `column_labels`: 컬럼 한글 라벨 (레거시 호환)
4. **input_type으로 타입 구분**: text, number, date, code, entity, select, checkbox, radio, textarea
5. **ON CONFLICT 절 필수**: 중복 시 UPDATE 처리
### 금지 사항
- `SERIAL`, `INTEGER`, `NUMERIC`, `BOOLEAN`, `TEXT`, `DATE` 등 DB 타입 직접 사용 금지
- `VARCHAR` 길이 변경 금지 (반드시 500)
- 기본 5개 컬럼 누락 금지
- 메타데이터 테이블 미등록 금지

View File

@ -3574,7 +3574,7 @@ export async function getTableSchema(
ic.character_maximum_length,
ic.numeric_precision,
ic.numeric_scale,
COALESCE(ttc_company.column_label, ttc_common.column_label) AS column_label,
COALESCE(NULLIF(ttc_company.column_label, ic.column_name), ttc_common.column_label) AS column_label,
COALESCE(ttc_company.display_order, ttc_common.display_order) AS display_order,
COALESCE(ttc_company.is_nullable, ttc_common.is_nullable) AS ttc_is_nullable,
COALESCE(ttc_company.is_unique, ttc_common.is_unique) AS ttc_is_unique

View File

@ -972,7 +972,7 @@ class MultiTableExcelService {
c.column_name,
c.is_nullable AS db_is_nullable,
c.column_default,
COALESCE(ttc.column_label, cl.column_label) AS column_label,
COALESCE(NULLIF(ttc.column_label, c.column_name), cl.column_label) AS column_label,
COALESCE(ttc.reference_table, cl.reference_table) AS reference_table,
COALESCE(ttc.is_nullable, cl.is_nullable) AS ttc_is_nullable
FROM information_schema.columns c

View File

@ -190,7 +190,7 @@ export class TableManagementService {
? await query<any>(
`SELECT
c.column_name as "columnName",
COALESCE(ttc.column_label, cl.column_label, c.column_name) as "displayName",
COALESCE(NULLIF(ttc.column_label, c.column_name), cl.column_label, c.column_name) as "displayName",
c.data_type as "dataType",
c.data_type as "dbType",
COALESCE(ttc.input_type, cl.input_type, 'text') as "webType",