cors 문제 해결 .
This commit is contained in:
parent
dd03c2aecd
commit
b0b787a8ce
@ -3,7 +3,7 @@ import json
|
|||||||
from typing import Any, Union
|
from typing import Any, Union
|
||||||
|
|
||||||
from fastapi import Depends
|
from fastapi import Depends
|
||||||
from fastapi.responses import ORJSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
||||||
import bcrypt
|
import bcrypt
|
||||||
from jose import jwt, JWTError, ExpiredSignatureError
|
from jose import jwt, JWTError, ExpiredSignatureError
|
||||||
@ -109,5 +109,7 @@ def RemoveNoneValues(obj: Any) -> Any:
|
|||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
def RemoveNoneResponse(obj) -> ORJSONResponse:
|
def RemoveNoneResponse(obj) -> JSONResponse:
|
||||||
return ORJSONResponse(content=RemoveNoneValues(obj.model_dump()))
|
# mode="json": datetime/uuid 등을 JSON-safe 문자열로 변환(표준 JSONResponse 가 직렬화 가능).
|
||||||
|
# (ORJSONResponse 는 최신 FastAPI 에서 deprecated)
|
||||||
|
return JSONResponse(content=RemoveNoneValues(obj.model_dump(mode="json")))
|
||||||
|
|||||||
@ -35,6 +35,7 @@ class MainTableMixin(_DBTypeMixin):
|
|||||||
# ERD 도메인 모델
|
# ERD 도메인 모델
|
||||||
class companies(MainTableMixin, MAIN_BASE):
|
class companies(MainTableMixin, MAIN_BASE):
|
||||||
__tablename__ = "companies"
|
__tablename__ = "companies"
|
||||||
|
__table_args__ = {"schema": "company"}
|
||||||
|
|
||||||
company_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
company_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
name = Column(String(100), nullable=False)
|
name = Column(String(100), nullable=False)
|
||||||
@ -50,6 +51,7 @@ class companies(MainTableMixin, MAIN_BASE):
|
|||||||
|
|
||||||
class users(MainTableMixin, MAIN_BASE):
|
class users(MainTableMixin, MAIN_BASE):
|
||||||
__tablename__ = "users"
|
__tablename__ = "users"
|
||||||
|
__table_args__ = {"schema": "company"}
|
||||||
|
|
||||||
user_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
user_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
company_id = Column(UUID(as_uuid=True), nullable=False, index=True)
|
company_id = Column(UUID(as_uuid=True), nullable=False, index=True)
|
||||||
@ -65,6 +67,7 @@ class users(MainTableMixin, MAIN_BASE):
|
|||||||
|
|
||||||
class items(MainTableMixin, MAIN_BASE):
|
class items(MainTableMixin, MAIN_BASE):
|
||||||
__tablename__ = "items"
|
__tablename__ = "items"
|
||||||
|
__table_args__ = {"schema": "partner"}
|
||||||
|
|
||||||
item_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
item_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
company_id = Column(UUID(as_uuid=True), nullable=False, index=True)
|
company_id = Column(UUID(as_uuid=True), nullable=False, index=True)
|
||||||
@ -94,6 +97,7 @@ class items(MainTableMixin, MAIN_BASE):
|
|||||||
|
|
||||||
class suppliers(MainTableMixin, MAIN_BASE):
|
class suppliers(MainTableMixin, MAIN_BASE):
|
||||||
__tablename__ = "suppliers"
|
__tablename__ = "suppliers"
|
||||||
|
__table_args__ = {"schema": "partner"}
|
||||||
|
|
||||||
supplier_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
supplier_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
company_id = Column(UUID(as_uuid=True), nullable=False, index=True)
|
company_id = Column(UUID(as_uuid=True), nullable=False, index=True)
|
||||||
@ -109,6 +113,7 @@ class suppliers(MainTableMixin, MAIN_BASE):
|
|||||||
|
|
||||||
class nego_cards(MainTableMixin, MAIN_BASE):
|
class nego_cards(MainTableMixin, MAIN_BASE):
|
||||||
__tablename__ = "nego_cards"
|
__tablename__ = "nego_cards"
|
||||||
|
__table_args__ = {"schema": "card"}
|
||||||
|
|
||||||
nego_card_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
nego_card_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
user_id = Column(UUID(as_uuid=True), nullable=True, index=True) # 등록 유저(o2o 기본 카드는 NULL)
|
user_id = Column(UUID(as_uuid=True), nullable=True, index=True) # 등록 유저(o2o 기본 카드는 NULL)
|
||||||
@ -120,6 +125,7 @@ class nego_cards(MainTableMixin, MAIN_BASE):
|
|||||||
|
|
||||||
class wild_cards(MainTableMixin, MAIN_BASE):
|
class wild_cards(MainTableMixin, MAIN_BASE):
|
||||||
__tablename__ = "wild_cards"
|
__tablename__ = "wild_cards"
|
||||||
|
__table_args__ = {"schema": "card"}
|
||||||
|
|
||||||
wild_card_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
wild_card_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
user_id = Column(UUID(as_uuid=True), nullable=True, index=True) # 등록 유저(o2o 기본 카드는 NULL)
|
user_id = Column(UUID(as_uuid=True), nullable=True, index=True) # 등록 유저(o2o 기본 카드는 NULL)
|
||||||
@ -134,6 +140,7 @@ class wild_cards(MainTableMixin, MAIN_BASE):
|
|||||||
|
|
||||||
class quotation_settings(MainTableMixin, MAIN_BASE):
|
class quotation_settings(MainTableMixin, MAIN_BASE):
|
||||||
__tablename__ = "quotation_settings"
|
__tablename__ = "quotation_settings"
|
||||||
|
__table_args__ = {"schema": "quotation"}
|
||||||
|
|
||||||
qt_setting_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
qt_setting_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
user_id = Column(UUID(as_uuid=True), nullable=True, index=True) # 설정 소유 유저
|
user_id = Column(UUID(as_uuid=True), nullable=True, index=True) # 설정 소유 유저
|
||||||
@ -144,6 +151,7 @@ class quotation_settings(MainTableMixin, MAIN_BASE):
|
|||||||
|
|
||||||
class quotations(MainTableMixin, MAIN_BASE):
|
class quotations(MainTableMixin, MAIN_BASE):
|
||||||
__tablename__ = "quotations"
|
__tablename__ = "quotations"
|
||||||
|
__table_args__ = {"schema": "quotation"}
|
||||||
|
|
||||||
qt_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
qt_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
user_id = Column(UUID(as_uuid=True), nullable=False, index=True)
|
user_id = Column(UUID(as_uuid=True), nullable=False, index=True)
|
||||||
@ -173,6 +181,7 @@ class quotations(MainTableMixin, MAIN_BASE):
|
|||||||
|
|
||||||
class sessions(MainTableMixin, MAIN_BASE):
|
class sessions(MainTableMixin, MAIN_BASE):
|
||||||
__tablename__ = "sessions"
|
__tablename__ = "sessions"
|
||||||
|
__table_args__ = {"schema": "negotiation"}
|
||||||
|
|
||||||
session_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
session_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
quotation_id = Column(UUID(as_uuid=True), nullable=False, index=True) # 소속 견적(quotations.qt_id)
|
quotation_id = Column(UUID(as_uuid=True), nullable=False, index=True) # 소속 견적(quotations.qt_id)
|
||||||
@ -194,6 +203,7 @@ class sessions(MainTableMixin, MAIN_BASE):
|
|||||||
|
|
||||||
class chats(MainTableMixin, MAIN_BASE):
|
class chats(MainTableMixin, MAIN_BASE):
|
||||||
__tablename__ = "chats"
|
__tablename__ = "chats"
|
||||||
|
__table_args__ = {"schema": "negotiation"}
|
||||||
|
|
||||||
chat_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
chat_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
session_id = Column(UUID(as_uuid=True), nullable=False, index=True) # 소속 세션(sessions.session_id)
|
session_id = Column(UUID(as_uuid=True), nullable=False, index=True) # 소속 세션(sessions.session_id)
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import json
|
|||||||
from typing import Any, Union
|
from typing import Any, Union
|
||||||
|
|
||||||
from fastapi import Depends
|
from fastapi import Depends
|
||||||
from fastapi.responses import ORJSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
||||||
import bcrypt
|
import bcrypt
|
||||||
from jose import jwt, JWTError, ExpiredSignatureError
|
from jose import jwt, JWTError, ExpiredSignatureError
|
||||||
@ -109,7 +109,8 @@ def RemoveNoneValues(obj: Any) -> Any:
|
|||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
def RemoveNoneResponse(obj) -> ORJSONResponse:
|
def RemoveNoneResponse(obj) -> JSONResponse:
|
||||||
# mode="json": uuid/datetime 등 DB 네이티브 타입(asyncpg.UUID 포함)을 pydantic 단에서
|
# mode="json": uuid/datetime 등 DB 네이티브 타입(asyncpg.UUID 포함)을 pydantic 단에서
|
||||||
# JSON 안전한 문자열로 변환한다. (python 모드면 orjson 이 asyncpg.UUID 를 직렬화 못 함)
|
# JSON 안전한 문자열로 변환한다. content 가 이미 JSON-safe dict 이므로 표준 JSONResponse 사용
|
||||||
return ORJSONResponse(content=RemoveNoneValues(obj.model_dump(mode="json")))
|
# (ORJSONResponse 는 최신 FastAPI 에서 deprecated).
|
||||||
|
return JSONResponse(content=RemoveNoneValues(obj.model_dump(mode="json")))
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
FROM node:20-alpine
|
# node 22 (orval 은 node>=22.18 요구) + Debian slim(glibc) — alpine(musl)+esbuild 의 ETXTBSY 회피.
|
||||||
|
FROM node:22-slim
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
|||||||
@ -151,7 +151,7 @@ CREATE TABLE IF NOT EXISTS partner.items (
|
|||||||
lead_time SMALLINT NULL, -- 상품 주문 완료 후, 배송 도착까지의 시간
|
lead_time SMALLINT NULL, -- 상품 주문 완료 후, 배송 도착까지의 시간
|
||||||
manufacturer VARCHAR(50) NULL, -- 제조사
|
manufacturer VARCHAR(50) NULL, -- 제조사
|
||||||
made_in VARCHAR(100) NULL, -- 원산지
|
made_in VARCHAR(100) NULL, -- 원산지
|
||||||
quantity_unit SMALLINT NULL, -- 상품 취급 단위 (코드: 예 EA/BOX/SET, 앱 enum 매핑)
|
quantity_unit VARCHAR(50) NULL, -- 상품 취급 단위 라벨(자유입력): EA/BOX/SET/ROLL ... (ORM String 기준)
|
||||||
delivery_type SMALLINT NULL, -- 배송 유형 (코드, 앱 enum 매핑)
|
delivery_type SMALLINT NULL, -- 배송 유형 (코드, 앱 enum 매핑)
|
||||||
vat_yn BOOLEAN NULL, -- 부가세 포함 여부
|
vat_yn BOOLEAN NULL, -- 부가세 포함 여부
|
||||||
delivery_fee_yn BOOLEAN NULL, -- 배송비 포함 여부
|
delivery_fee_yn BOOLEAN NULL, -- 배송비 포함 여부
|
||||||
|
|||||||
@ -13,13 +13,13 @@ WHERE NOT EXISTS (
|
|||||||
SELECT 1 FROM company.companies WHERE company_id = '00000000-0000-0000-0000-000000000001'
|
SELECT 1 FROM company.companies WHERE company_id = '00000000-0000-0000-0000-000000000001'
|
||||||
);
|
);
|
||||||
|
|
||||||
-- admin 유저. password 는 'admin1234' 의 bcrypt 해시(백엔드 GetHashedPW 와 동일 알고리즘, checkpw 로 검증됨).
|
-- admin 유저. password 는 'admin123' 의 bcrypt 해시(백엔드 GetHashedPW 와 동일 알고리즘, checkpw 로 검증됨).
|
||||||
-- role 2=manager (UserRole.MANAGER; ADMIN 코드는 enum 에 없어 최상위인 MANAGER 사용). status 1=active.
|
-- role 2=manager (UserRole.MANAGER; ADMIN 코드는 enum 에 없어 최상위인 MANAGER 사용). status 1=active.
|
||||||
INSERT INTO company.users (user_id, company_id, id, password, name, email, last_accessed_at, status, role)
|
INSERT INTO company.users (user_id, company_id, id, password, name, email, last_accessed_at, status, role)
|
||||||
SELECT '00000000-0000-0000-0000-000000000002',
|
SELECT '00000000-0000-0000-0000-000000000002',
|
||||||
'00000000-0000-0000-0000-000000000001',
|
'00000000-0000-0000-0000-000000000001',
|
||||||
'admin',
|
'admin',
|
||||||
'$2b$12$oq5qlcYQ4BNywh9iS7cF1OBP6kGBvB6SfsGgVknCiJ6lMSW5cjW.C',
|
'$2b$12$KY4T0kXQ2npvvt71iWZG0.JZHlMNt9angIkE/7.lBC4vta4dHgrj2',
|
||||||
'admin', 'admin@negosium.dev', now(), 1, 2
|
'admin', 'admin@negosium.dev', now(), 1, 2
|
||||||
WHERE NOT EXISTS (
|
WHERE NOT EXISTS (
|
||||||
SELECT 1 FROM company.users WHERE id = 'admin' AND deleted = FALSE
|
SELECT 1 FROM company.users WHERE id = 'admin' AND deleted = FALSE
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user