Files
Aislo/.agent/test/02_Database_Schema.md
T

61 lines
3.4 KiB
Markdown

---
document_type: database
priority: CRITICAL
---
# 데이터베이스 스키마 명세 (MariaDB)
MariaDB v10.6+를 사용하며, 총 18개의 테이블로 구성됩니다. ORM 없이 Raw SQL과 `aiomysql` 드라이버를 사용합니다. **공간 데이터(GEOMETRY)는 지원 한계로 인해 JSONB 또는 TEXT(GeoJSON)로 저장합니다.**
## 테이블 목록 및 컬럼 구조
### 1. 사용자 & 프로젝트 (Core)
* **`users`**: `id`(PK), `email`, `password_hash`, `name`, `position`, `department`, `phone`, `company_id`(FK)
* **`companies`**: `id`(PK), `name`, `business_registration_number`, `business_address`, `business_owner`, `business_status`
* **`projects`**: `id`(UUID, PK), `user_id`(FK), `company_id`(FK), `name`, `region`, `road_type`, `status`, `crs_epsg`, `storage_path`
* **`project_versions`**: `id`, `project_id`, `version_num`, `data`(JSONB)
### 2. 파일 & 지표면 데이터 (WF0, WF1)
* **`input_files`**: `id`(PK), `project_id`(FK), `file_type`(las, tif 등), `original_filename`, `raw_file_path`, `crs_epsg`, `metadata`(JSONB)
* **`processed_point_cloud`**: `id`, `input_file_id`, `project_id`, `processed_file_path`, `converted_file_path`, `min_z`, `max_z` 등 통계치
* **`surface_models`**: `id`, `project_id`, `model_type`(dem_grid, tin 등), `model_file_path`, `generation_params`(JSONB)
* **`terrain_layers`**: `id`, `surface_model_id`, `layer_name`, `layer_file_path`(geojson 등)
### 3. 경로 설계 (WF2)
* **`routes`**: `id`(PK), `project_id`, `surface_model_id`, `status`, `geometry`(LineString JSON), `route_data_path`, `constraints`(JSONB)
* **`route_points`**: `id`, `route_id`, `chainage_m`, `geometry`(Point JSON), `elevation_m`
* **`route_statistics`**: `id`, `route_id`, `mean_slope`, `cut_volume_m3`, `fill_volume_m3`
### 4. 종횡단 및 구조물 설계 (WF3, WF4)
* **`longitudinal_sections`**: `id`, `project_id`, `route_id`, `longitudinal_file_path`, `data`(JSONB - chainages, elevations 등 배열)
* **`cross_sections`**: `id`, `route_id`, `chainage_m`, `cross_section_file_path`, `data`(JSONB - left_slope, cut_volume_m3 등)
* **`structures`**: `id`, `cross_section_id`, `structure_type`, `location`(LEFT/RIGHT/CENTER), `length_m`, `geometry`(Polygon JSON), `structure_data_path`
### 5. 수량 산출 및 산출물 (WF5, WF6)
* **`quantity_items`**: `id`, `project_id`, `category`, `item_name`, `quantity_design`, `quantity_actual`, `unit_price`, `quantity_data_path`
* **`outputs`**: `id`, `project_id`, `output_type`, `outputs_directory_path`
* **`output_files`**: `id`, `output_id`, `file_type`, `output_file_path`
### 6. 로그 (Audit)
* **`audit_logs`**, **`change_logs`**
---
## 💡 주요 원칙 (DB vs File System)
- **DB에는 메타데이터와 파일 시스템의 "상대 경로"만 기록합니다.** (예: `input_files.raw_file_path = "B03_FileInput/input/las/cloud.las"`)
- 대용량 파일(LAS, TIF, GeoJSON)은 MariaDB에 Blob으로 저장하지 않습니다.
## 📝 쿼리 작성 예제 (Raw SQL & aiomysql)
```python
# 쿼리에는 ORM이 아닌 %s 플레이스홀더를 사용해야 함
async def get_project_route(pool, project_id: str):
async with pool.acquire() as conn:
async with conn.cursor() as cur:
await cur.execute("""
SELECT r.id, r.total_length_m, r.route_data_path
FROM routes r
WHERE r.project_id = %s
ORDER BY r.computed_at DESC LIMIT 1
""", (project_id,))
return await cur.fetchone()
```