[docs] negodata: README 갱신 — 테스트 실행법·API 도메인·프론트 포트
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
82076e138e
commit
43ac308a5e
@ -1,6 +1,6 @@
|
|||||||
# Negodata Backend
|
# Negodata Backend
|
||||||
|
|
||||||
DerbyMasters_Server 아키텍처를 이식한 FastAPI 골격. 기능은 **JWT id/pw 로그인**만 예시 구현.
|
DerbyMasters_Server 아키텍처를 이식한 FastAPI 백엔드. 인증(JWT) 위에 **견적·협력사·상품·견적설정·대시보드·알림·협상카드·회사유저관리** 도메인과 **견적 마감 스케줄러**를 구현.
|
||||||
[negosium-backend](../../backend/README.md) 와 동일 구조이며, 실행·테스트·벤치마크 종합은 [레포 최상위 README](../../README.md) 참고.
|
[negosium-backend](../../backend/README.md) 와 동일 구조이며, 실행·테스트·벤치마크 종합은 [레포 최상위 README](../../README.md) 참고.
|
||||||
|
|
||||||
## 디렉토리 구조
|
## 디렉토리 구조
|
||||||
@ -9,19 +9,20 @@ DerbyMasters_Server 아키텍처를 이식한 FastAPI 골격. 기능은 **JWT id
|
|||||||
negodata/backend/
|
negodata/backend/
|
||||||
├── web_main.py # 엔트리포인트 (uvicorn)
|
├── web_main.py # 엔트리포인트 (uvicorn)
|
||||||
├── config/ # 환경설정 (APP_ENV 별 toml 로드)
|
├── config/ # 환경설정 (APP_ENV 별 toml 로드)
|
||||||
|
├── conftest.py, tests/ # pytest (test DB 자동 create/drop) — 아래 '테스트'
|
||||||
├── common/
|
├── common/
|
||||||
│ ├── enums.py # ErrorType / DBType / DBWRType / EXCEPTION_*
|
│ ├── enums.py # ErrorType / 코드값 enum / EXCEPTION_*
|
||||||
│ ├── models/gmodel.py # 프로토콜 베이스 (WebPacketProtocol 등)
|
│ ├── models/gmodel.py # 프로토콜 베이스 (WebPacketProtocol 등)
|
||||||
│ └── database/
|
│ └── database/
|
||||||
│ ├── db_session_manager.py# ★ DB Read/Write + 람다 실행 핵심
|
│ ├── db_session_manager.py# ★ DB Read/Write + 람다 실행 핵심
|
||||||
│ └── model/models.py # ORM 모델 (tbl_account)
|
│ └── model/models.py # ORM 모델 (companies·users·quotations·sessions·items·suppliers·notifications·cards …)
|
||||||
├── crud/user_crud.py # DB 접근 (I*CRUD 인터페이스 + 구현)
|
├── crud/ # 도메인별 DB 접근(I*CRUD 인터페이스+구현): quotation·supplier·item·dashboard·notification·card·user …
|
||||||
├── services/auth_service.py # 비즈니스 로직
|
├── services/ # 비즈니스 로직: quotation·supplier·item·dashboard·notification·company_user·auth·email …
|
||||||
|
├── scheduler/ # 견적 마감 크론 잡(만료 마감 · 협상종결 마감)
|
||||||
└── router/
|
└── router/
|
||||||
├── router.py # FastAPI app
|
├── router.py # FastAPI app (CORS 등)
|
||||||
└── v1/
|
└── v1/ # 도메인별 라우터: auth·quotation·quotation_setting·supplier·item·card·dashboard·notification·company
|
||||||
├── auth/{account,protocol}.py # 엔드포인트 / Req_·Res_
|
└── validator/dependencies.py # ★ JWT 발급·검증, 해시(bcrypt), RemoveNoneResponse, RequireOwner
|
||||||
└── validator/dependencies.py # ★ JWT 발급·검증, 해시, RemoveNoneResponse
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 핵심 패턴
|
## 핵심 패턴
|
||||||
@ -40,22 +41,53 @@ negodata/backend/
|
|||||||
- **ResponseNone**: 응답의 `None` 필드 재귀 제거(`RemoveNoneResponse`).
|
- **ResponseNone**: 응답의 `None` 필드 재귀 제거(`RemoveNoneResponse`).
|
||||||
- **bcrypt 비차단**: `GetHashedPW`/`VerifyPW` 를 `asyncio.to_thread` 로 오프로드(이벤트 루프 비차단). → [벤치마크](../../README.md#성능--벤치마크)
|
- **bcrypt 비차단**: `GetHashedPW`/`VerifyPW` 를 `asyncio.to_thread` 로 오프로드(이벤트 루프 비차단). → [벤치마크](../../README.md#성능--벤치마크)
|
||||||
|
|
||||||
## 엔드포인트
|
## API 도메인 (`/v1/*`)
|
||||||
| Method | Path | 설명 |
|
전체 스펙은 실행 후 **http://localhost:9400/docs** (Swagger). 주요 도메인:
|
||||||
|---|---|---|
|
|
||||||
| POST | `/v1/auth/create` | 계정 생성 (pw bcrypt 해시) |
|
|
||||||
| POST | `/v1/auth/login` | 로그인, access/refresh 토큰 발급 |
|
|
||||||
| POST | `/v1/auth/refresh_token` | access 토큰 재발급 (refresh 필요) |
|
|
||||||
| GET | `/v1/auth/me` | 내 정보 (access 토큰 필요) |
|
|
||||||
|
|
||||||
## 실행 / 테스트
|
| prefix | 요약 |
|
||||||
|
|---|---|
|
||||||
|
| `/v1/auth` | 로그인 · access 토큰 재발급 · 내 정보(`me`). ※ 무인증 계정 생성은 제거됨 |
|
||||||
|
| `/v1/company/user` | 최고관리자(OWNER) 전용 — 자기 회사 직원 계정 생성·관리 |
|
||||||
|
| `/v1/quotation` | 견적 생성·목록·단건·마감·재생성 + 세션·채팅·낙찰결과·카드·초청메일 |
|
||||||
|
| `/v1/quotation-setting` | 견적 설정(마진율 등) — **유저별** 소유 |
|
||||||
|
| `/v1/supplier`, `/v1/item` | 협력사 / 상품 CRUD (회사 스코프) |
|
||||||
|
| `/v1/card` | 협상 카드 |
|
||||||
|
| `/v1/dashboard` | 요약(회사 전체 + 내 견적) |
|
||||||
|
| `/v1/notification` | 알림함(목록 · 읽음 처리) |
|
||||||
|
|
||||||
|
> 인증 헤더: `Authorization: Bearer <access_token>`. 회사 소유 자원은 토큰의 회사로 스코프되고, 계정 관리는 OWNER 만 가능.
|
||||||
|
|
||||||
|
## 실행
|
||||||
```bash
|
```bash
|
||||||
# 레포 최상위에서 docker compose up -d (backend만; DB 는 외부 PostgreSQL). 상세는 루트 README.
|
|
||||||
cd negodata/backend
|
cd negodata/backend
|
||||||
pip install -r requirements.txt # 실행
|
pip install -r requirements.txt
|
||||||
python web_main.py # APP_ENV 기본 local
|
python web_main.py # APP_ENV 기본 local → http://localhost:9400/docs
|
||||||
pip install pytest pytest-asyncio httpx # 테스트 도구
|
|
||||||
python -m pytest
|
|
||||||
```
|
```
|
||||||
- 서버: http://localhost:9400/docs
|
환경: `config.{local,test,prod}.toml` (`APP_ENV` 로 선택).
|
||||||
- 환경: `config.{local,test,docker}.toml` (`APP_ENV` 로 선택, docker 는 DB 호스트=`host.docker.internal`, database=`negodata_db`)
|
|
||||||
|
## 테스트
|
||||||
|
|
||||||
|
**테스트는 도커가 아니라 호스트(venv)에서 돌린다** — DB(PostgreSQL)만 도커(`negosium-db`, `127.0.0.1:5432`)면 되고, 앱 컨테이너 안엔 pytest 가 없다. test DB(`negosium_test_db`)는 알아서 만들어졌다 지워지므로 **수동 세팅이 필요 없다.**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd negodata/backend
|
||||||
|
python3 -m venv .venv && source .venv/bin/activate # 최초 1회 (venv 없을 때)
|
||||||
|
pip install -r requirements.txt # httpx 포함
|
||||||
|
pip install pytest pytest-asyncio # 테스트 도구(requirements 에 없음)
|
||||||
|
|
||||||
|
python -m pytest # 전체 (venv 활성화 상태)
|
||||||
|
python -m pytest -v # 테스트별 PASS/FAIL
|
||||||
|
python -m pytest tests/test_company_scope.py # 파일 하나만
|
||||||
|
python -m pytest -k scope # 이름에 'scope' 든 것만
|
||||||
|
```
|
||||||
|
venv 를 활성화(`source .venv/bin/activate`)하지 않으면 `.venv/bin/python -m pytest` 로 직접 지정한다.
|
||||||
|
(시스템에 `python` 명령이 없거나 pytest 가 venv 밖에 없으면 맨 `python -m pytest` 는 실패한다.)
|
||||||
|
정상이면 마지막 줄에 `NN passed`.
|
||||||
|
|
||||||
|
동작 방식 (전부 [conftest.py](conftest.py) 가 자동 처리 — 손댈 것 없음):
|
||||||
|
- `APP_ENV` 를 `test` 로 자동 설정 → [config.test.toml](config/config.test.toml) 의 **`negosium_test_db`** 사용(dev DB `negosium_db` 와 완전 분리).
|
||||||
|
- **세션 시작 시 test DB 를 새로 만들고(CREATE), 끝나면 내린다(DROP).** 매번 현재 모델로 새로 빌드돼 스키마가 낡을 일이 없다. 남는 DB 도 없음.
|
||||||
|
- 테이블은 `create_all` 로 자동 생성, 매 테스트 전 `TRUNCATE` 로 비워 격리.
|
||||||
|
- 안전가드: 이름에 `test` 없는 DB 는 만들지도 지우지도 않는다(실 DB 보호).
|
||||||
|
|
||||||
|
> 즉 새로 clone 받은 팀원도 **Postgres 만 켜져 있으면 `python -m pytest` 한 방**이면 끝.
|
||||||
|
|||||||
@ -21,8 +21,9 @@ negosium/negodata 협상 플랫폼의 웹 프론트엔드.
|
|||||||
docker compose up -d --build
|
docker compose up -d --build
|
||||||
```
|
```
|
||||||
|
|
||||||
- 프론트: **http://localhost:3001** (compose 가 컨테이너 `:3000` → 호스트 `:3001` 로 매핑)
|
- 프론트: **http://localhost:3000** (compose 서비스 `negodata-front`, `3000:3000` 매핑)
|
||||||
- 소스를 바인드마운트하므로 코드 수정은 HMR 로 자동 반영된다.
|
- 소스를 바인드마운트하므로 코드 수정은 HMR 로 자동 반영된다.
|
||||||
|
- (참고: 공급사용 `negosium-front` 는 별개로 `:3300`)
|
||||||
|
|
||||||
### 프론트만 단독 개발 (선택)
|
### 프론트만 단독 개발 (선택)
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ src/
|
|||||||
api/
|
api/
|
||||||
generated/ # orval 자동생성 (직접 수정 금지)
|
generated/ # orval 자동생성 (직접 수정 금지)
|
||||||
mutator/ # custom-fetch (요청 공통 로직: baseURL·토큰·에러)
|
mutator/ # custom-fetch (요청 공통 로직: baseURL·토큰·에러)
|
||||||
features/ # 도메인별: auth, products(상품), partners(협력사), quotations(견적), cards
|
features/ # 도메인별: auth, quotations(견적), products(상품), partners(협력사), cards(협상카드), dashboard, members(회원관리), onboarding
|
||||||
components/ # ui(shadcn), layout
|
components/ # ui(shadcn), layout
|
||||||
pages/ # 화면
|
pages/ # 화면
|
||||||
stores/ # zustand 스토어
|
stores/ # zustand 스토어
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user