feat(momo): 모모유통 유통관리 ERP 1차 구축 (가입/품목/재고/발주/명세서/메일)
- DB: momo_* 테이블 12종 (users/items/makers/warehouses/stocks/stock_moves/orders/order_items/procurements/vendors/attachments/mail_logs) + 시드 - 인증: 랜딩(/) + 회원가입(/signup, bcrypt) + 로그인(MOMO/FITO 자동 분기) + /api/auth/mobile-login(JWT 토큰) - 세션: 쿠키 + Authorization Bearer 동시 지원 (모바일 앱용) - /m/* 레이아웃: 좌측 사이드바 + 헤더, 역할별 메뉴 분기 - USER 화면: 품목 검색(이미지/재고/단가) + 장바구니 + 발주 요청 + 본인 이력 + 대시보드 - ADMIN 화면: 품목/창고/재고/매입입고/발주승인/회원관리/월간 매출 통계 + 대시보드(14일 그래프, 재고 부족, 승인 대기) - 발주 승인: 트랜잭션으로 재고 차감 + 거래명세표 HTML 메일 본문 + xlsx 첨부 발송 (nodemailer) - 면세 자동 판정: 품목명 'M' 접두 시 is_tax_free=Y, 합계는 면세/과세 분리 집계 - 미들웨어: /, /signup, /api/auth/signup, /api/auth/mobile-login 공개 - 도구: scripts/migrate-momo.mjs (npm run migrate:momo), .env.momo.example - 문서: docs/MOMO_DISTRIBUTION_SPEC.md, docs/proposal.html (고객용 HTML 제안서) - 별도 RN 앱(d:/momo-mobile) 스캐폴드 작성 (Expo + EAS APK 빌드) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
// 모모유통 마이그레이션 실행 스크립트
|
||||
// 사용법: node scripts/migrate-momo.mjs
|
||||
// .env.development 또는 .env.production 의 DATABASE_URL 사용
|
||||
|
||||
import pg from "pg";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const envFile = process.env.NODE_ENV === "production" ? ".env.production" : ".env.development";
|
||||
const envPath = path.join(__dirname, "..", envFile);
|
||||
if (fs.existsSync(envPath)) {
|
||||
for (const line of fs.readFileSync(envPath, "utf-8").split(/\r?\n/)) {
|
||||
const m = line.match(/^([A-Z_][A-Z0-9_]*)=(.*)$/);
|
||||
if (m) process.env[m[1]] ??= m[2].replace(/^["']|["']$/g, "");
|
||||
}
|
||||
}
|
||||
|
||||
const dir = path.join(__dirname, "..", "db", "migrations");
|
||||
const files = fs.readdirSync(dir).filter((f) => f.endsWith(".sql")).sort();
|
||||
const conn = process.env.DATABASE_URL;
|
||||
if (!conn) {
|
||||
console.error("DATABASE_URL 환경변수가 설정되지 않았습니다.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const client = new pg.Client({ connectionString: conn });
|
||||
await client.connect();
|
||||
console.log(`[migrate] DB connected. Running ${files.length} files...`);
|
||||
for (const f of files) {
|
||||
const sql = fs.readFileSync(path.join(dir, f), "utf-8");
|
||||
console.log(` → ${f}`);
|
||||
try {
|
||||
await client.query(sql);
|
||||
} catch (err) {
|
||||
console.error(` ✖ ${f} 실패:`, err.message);
|
||||
await client.end();
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
console.log("[migrate] ✔ 완료");
|
||||
await client.end();
|
||||
Reference in New Issue
Block a user