๐ ์์ธ ๋ด์ญ
์ฃผ์ ๋ณ ์์ธ ๋ด์ฉ. ๋ชฉ์ฐจ(์ฃผ์ ์์ธ)์ ๋ฒํธ์ ๋์. ํ์ /์งํ์ค/๋ฏธ๊ฒฐ์ ๊ตฌ๋ถํ๋ค.
A. ์ธํ๋ผ ยท ํ๊ฒฝ
| ํ๊ฒฝ | ํฌํธ | ์ฑ | ๋ธ๋์น | ๋๋ฉ์ธ | RDS |
|---|---|---|---|---|---|
| ์ด์ | 8000 | pfs | deploy-live | pfs.poin.co.kr | poin-dbinstance |
| ํ ์คํธ | 8001 | pfs-test | master | pfs-test.poin.co.kr | poin-dbinstance-test |
- EC2 i-03225ba8bc12a929e / EIP 13.209.147.168 / SG sg-00426f1b66795f5f9 / DB pfs user admin. |
|||||
- .env: /home/ubuntu/env/pfs-{live,test}.env. ์ด์ service pfs-live.uwsgi.service. |
|||||
| - nginx ์ค์ ์ git ์ธ ์๋ฒํ์ผ โ reload๋ก ์ฆ์ ๋ฐ์(deploy ๋ถํ์). | |||||
๋ฐฐํฌ ๋ฉ์ปค๋์ฆ [ํ์ ]: push โ GitHub Actions(deploy.yml) โ SSM send-command โ git fetch+reset --hard origin/<branch> + ๋ฐฐํฌ์คํฌ๋ฆฝ. master๋ pfs-test ๋๋ ํฐ๋ฆฌ, deploy-live๋ pfs ๋๋ ํฐ๋ฆฌ. ์ด์ ๋ฐฐํฌ์คํฌ๋ฆฝ์ systemctl restart pfs-live.uwsgi.service(๊ณผ๊ฑฐ pgrep+kill-HUP ์ค๋ณต์ธ์คํด์ค ๋ฒ๊ทธ ์์ ๋จ). |
|||||
| ## B. ์์ ์ฒด๊ณ | |||||
3๋จ๊ณ ์์คํ
[ํ์ ] |
|||||
| - โ ์ง๋จ โ ์ฑํฐ๊ฐ ์์ธ์ ์ฝ๋/์บ์/๋ฐฐํฌ/DB ์ค ์ด๋์ธ์ง ํ์ . ํ์์ MCP ์ฆ์ ํ์ธ. ๋ถํ์ค์ฑ 0์ผ๋ก ๋ง๋ ๋ค ๋ค์ ๋จ๊ณ. | |||||
| - โก ์์ โ ์ ํํ ์์น+before/after .md ์์ฑ โ ์ฝ๋์๊ฒ ํฐ ๋ฌถ์ ํ ๋ฒ์. ๊ฒ์ฆ ๋๋ ๋ณ๊ฒฝ๋ง ๋ฌถ์์(๋ฏธ๊ฒ์ฆ ์ถ์ธก ๊ธ์ง). | |||||
| - โข ๋ถ๋ฆฌ โ ๋๋์ญ์ ยท์ด์๋ฐฐํฌยทDB๋ณ๊ฒฝยท๊ถํ๋ณ๊ฒฝ์ ๋ฌถ์์์ ๋นผ์ ๋ณ๋ ์น์ธ. | |||||
์ฑํฐ MCP ์ง์ vs ์ฝ๋ ์์ [ํ์ ] โ ์ฑํฐ ์ง์ (MCP)์ ์ฆ์๋ณ๋ก ์ํ: ์ง๋จยท๋จ๊ฑดํ์ธ์ ์ฑํฐ, ๋๋๋ฉํฐํ์ผ ์์ ์ ์ฝ๋. ํฐ ๋ฌถ์์ผ์๋ก ํจ์จโ ํต์ ๋ ฅโ โ ๊ฒ์ฆ์ผ๋ก ์์. (MCP ์ฐ๊ธฐ ์์
์ ์ด๋ฒ ์ธ์
์์ ์ฌ๋ฌ ์ฐจ๋ก ํ์์์ โ ๋๋ ํธ์ง์ ์ฝ๋ ์์ญ). |
|||||
| ## C. estimate v2 | |||||
QA #1~5 [์ปค๋ฐํ์ธ] (commit 5ee6663 ๋ฑ) โ ํ๋ชฉ์ ํ/๋น๊ณ /๋จ๊ฐ ํญ์ ์
๋ ฅ ํ์ฑํ(_isNew ์กฐ๊ฑด ์ ๊ฑฐ), cell-name resize:none/overflow:hidden, size-summary contenteditable ๊ณ ์ . |
|||||
QA #6~9 [์ปค๋ฐํ์ธ] (commit 7be87f5) โ cat-sel focus/click ์ keyword='' ๊ฐ์ ๋ก ์ ์ฒด๋ชฉ๋ก, ๊ธฐ๋ณธ ๋ง์ง 15.5โ10, menu_catalog ๋ฉ๋ด๋ช
๋ณ๊ฒฝ, company.margin_rate ์ปด๋ผ ์ถ๊ฐ. |
|||||
์ ์ฒด๋ง์ง ์๋๋ฐ์ [์ปค๋ฐํ์ธ] (commit f6126d3) โ site-search SQL์ company_no/company_member_no/company_margin_rate ์ถ๊ฐ. pickSite์์ ์ ํ ์
์ฒด margin_rate๋ฅผ ์ ์ฒด๋ง์ง ์๋ ๋ฐ์(์์ผ๋ฉด 10), ์๋/์๋ ๋ฐฐ์ง. ์ฌ์ฉ์ ์์ ์ ์๋ ์ ํ. ๋ถ๋ฌ์ค๊ธฐ ์ ์ ์ฅ๊ฐ=์๋. |
|||||
| ## D. ์ ์ฒด ๊ด๋ฆฌ ยท ๊ถํ | |||||
์
์ฒด ๊ด๋ฆฌ ํ์ด์ง [์ปค๋ฐํ์ธ] (commit 424c099) โ /admin/company-permission ์ ๋ชฉยท๋ฉ๋ด๋ช
"์
์ฒด ๊ด๋ฆฌ"๋ก. company_dao.update_company_margin_rate / user_admin_service.set_company_margin_rate / PUT /api/admin/company/<id>/margin-rate. ์ข:์
์ฒด๋ชฉ๋ก ์ฐ:์์ธ+๋ง์ง์จ+๊ถํ๋งคํธ๋ฆญ์ค. company/search๊ฐ a.* ๋ฐํ โ margin_rate ์๋ ํฌํจ. |
|||||
| > ๊ฒ์ฆ ์ผํ(์ค์): "๋ง์ง์จ์ด ์ ์ฒด ์ ์ฉ๋๋ค"๋ ์ฆ์์ ์ง๋จ ๊ฒฐ๊ณผ ๋ฐฑ์๋ยทDBยท๋ฐฐํฌ ๋ชจ๋ ์ ์, ์ค์ ์์ธ์ ๋ธ๋ผ์ฐ์ ์บ์์์. DB์์ ๋จ๊ฑด UPDATE affected=1 ์ฆ๋ช ์๋ฃ. | |||||
| ## E. ์ด์ ๋ฐฐํฌ | |||||
์ด์ RDS ์คํค๋ง ์ง๋จ [์ง๋จ์๋ฃ 2026-05-22] โ ์ด์์ ๋ถ์กฑํ ๊ฒ์ ๋จ 2๊ฐ์ง: company.margin_rate ์ปด๋ผ(์์), menu_catalog ๋ฉ๋ด๋ช
(์
์ฒด ๊ถํโ์
์ฒด ๊ด๋ฆฌ). estimate ์ปด๋ผ(estimate_div ๋ฑ)ยทPatch#32 ํ
์ด๋ธ(menu_catalog ๋ฑ 4๊ฐ)ยทdispatchยทestimate_detail_subยทESTIMATE_DIV common_code๋ ์ด๋ฏธ ์ด์ ์กด์ฌ. masterโdeploy-live ๋ณํฉ ์ถฉ๋ 0(merge-tree ๋ฏธ๋ฆฌ๋ณด๊ธฐ ํ์ธ). |
|||||
์ด์ ๋ฐฐํฌ ์ ์ฐจ [์ง์๋ฌธ์์ฑ] โ ์์: โ ์ด์RDS SQL(margin_rate ์ปด๋ผ append+๋ฉ๋ด๋ช
) โ โก deploy-live ๋ณํฉยทpush(์๋๋ฐฐํฌ) โ โข ๊ฒ์ฆ. ์ด์ : ์ปด๋ผ ๋จผ์ ์ถ๊ฐํด์ผ ๊ตฌ์ฝ๋ ๋ฌด์ค๋จ(๋ฏธ์ฐธ์กฐ). ALTER ๋ฝ ์ฃผ์: lock_wait_timeout=10, ์คํจ์ uWSGI ์ค๋จ fallback. |
|||||
| ## F. ๋๋ฒ๊น ํ์ต | |||||
- ์์
/PDF 0KB [ํด๊ฒฐ de4605a] โ Content-Disposition ํ๊ธ ํ์ผ๋ช
โ werkzeug latin1 ์ธ์ฝ๋ฉ ์คํจ โ 200+0bytes. safe_ascii๊ฐ c.isalnum()๋ง ๋ดค์ผ๋ Python3๋ ํ๊ธ๋ True. ์์ : (ord(c)<128 and c.isalnum()) or c in '-.'. ๊ตํ: uWSGI ๋๋ฒ๊ทธ๋ journalctl -u |
|||||
- send_file(BytesIO) ํธํ์ฑ [ํ์ ] โ uWSGI wsgi.file_wrapper ์ถฉ๋. make_response(buf.getvalue())+ํค๋ ์ง์ ์ฌ์ฉ. |
|||||
- ๋ก๋ฉ ์ต์ ํ [ํด๊ฒฐ 5bbaf87] โ nginx gzip(css/js/json/svg) 1.76MBโ0.45MB. base.html ์ธ๋ถ SDK(Daum/Kakao) ๋๊ธฐ๋ก๋ ์ ๊ฑฐ. ์ด์ ๋ฏธ์ ์ฉ(ํ
์คํธ๋ง). |
|||||
- ์์ ํด๋ ๋ฐ์์๋จ [ํ์ ] โ โ ์๋ฒํ์ผ grep โกgit pull ๊ถํ/safe.directory โขuWSGI ์ฌ์์ โฃ๋ธ๋ผ์ฐ์ ์ํฌ๋ฆฟ โคview-source. JS ์๋ฌ๋ ํ์ ์ฝ๋ ์ ์ฒด ์ฐจ๋จ. |
|||||
| ## G. ์ฝ๋ฉ ๊ท์ฝ (์์ฝ) | |||||
| - ํ์ผ ๋ค์ด๋ก๋: send_file(BytesIO) ร โ make_response(getvalue())+ํค๋. ํ๊ธํ์ผ๋ช RFC5987 + ASCIIํํฐ ord(c)<128. | |||||
| - args["key"] ร โ args.get("key",""). SELECT a.*+๋ช ์์ปด๋ผ ์ค๋ณต ร โ ๋ณ์นญ(AS). | |||||
| - JS: ์ ๊ท API URL apiURL(), ๋ฒํผ์ !important, ์ด๋ฒคํธ๋ $(document).ready ๋ด/์์, ready try/catch. | |||||
| - REST: POST /api/ |