diff --git a/backend/app.py b/backend/app.py new file mode 100644 index 0000000..ee620fa --- /dev/null +++ b/backend/app.py @@ -0,0 +1,166 @@ +from flask import Flask, request, jsonify +import psycopg2 +from contextlib import contextmanager + +app = Flask(__name__) + +@contextmanager +def get_db_connection(): + conn = psycopg2.connect( + host="localhost", + database="tkmp_db", + user="tkmp_user", + password="tkmp2024!", + port="5432" + ) + try: + yield conn + finally: + conn.close() + +@app.route('/') +def home(): + return {"message": "API 작동 중"} + +@app.route('/api/materials') +def get_materials(): + job_number = request.args.get('job_number') + + if not job_number: + return {"error": "job_number 필요"}, 400 + + try: + with get_db_connection() as conn: + cur = conn.cursor() + + cur.execute(""" + SELECT id, job_number, item_number, description, + category, quantity, unit, created_at + FROM materials + WHERE job_number = %s + ORDER BY item_number + """, (job_number,)) + + rows = cur.fetchall() + + materials = [] + for r in rows: + item = { + 'id': r[0], + 'job_number': r[1], + 'item_number': r[2], + 'description': r[3], + 'category': r[4], + 'quantity': r[5], + 'unit': r[6], + 'created_at': str(r[7]) if r[7] else None + } + materials.append(item) + + return { + 'success': True, + 'data': materials, + 'count': len(materials) + } + + except Exception as e: + return {"error": f"DB 오류: {str(e)}"}, 500 + +if __name__ == '__main__': + print("🚀 서버 시작: http://localhost:5000") + app.run(debug=True, port=5000) +# 수정된 get_materials API (올바른 컬럼명 사용) +@app.route('/api/materials-fixed', methods=['GET']) +def get_materials_fixed(): + """올바른 컬럼명을 사용한 자재 조회 API""" + try: + file_id = request.args.get('file_id') + + if not file_id: + return jsonify({ + 'success': False, + 'error': 'file_id parameter is required' + }), 400 + + with get_db_connection() as conn: + cur = conn.cursor() + + cur.execute(""" + SELECT + id, file_id, line_number, original_description, + classified_category, classified_subcategory, + quantity, unit, created_at + FROM materials + WHERE file_id = %s + ORDER BY line_number + """, (file_id,)) + + materials = [] + for item in cur.fetchall(): + material = { + 'id': item[0], + 'file_id': item[1], + 'line_number': item[2], + 'original_description': item[3], + 'classified_category': item[4], + 'classified_subcategory': item[5], + 'quantity': float(item[6]) if item[6] else 0, + 'unit': item[7], + 'created_at': item[8].isoformat() if item[8] else None + } + materials.append(material) + + return jsonify({ + 'success': True, + 'data': materials, + 'count': len(materials), + 'file_id': file_id + }) + + except Exception as e: + print(f"Error in get_materials_fixed: {e}") + return jsonify({ + 'success': False, + 'error': str(e) + }), 500 + +@app.get("/api/materials-test") +def get_materials_test(file_id: int): + """테스트용 자재 조회 API""" + try: + with get_db_connection() as conn: + cur = conn.cursor() + + cur.execute(""" + SELECT + id, file_id, line_number, original_description, + classified_category, quantity, unit + FROM materials + WHERE file_id = %s + ORDER BY line_number + LIMIT 5 + """, (file_id,)) + + rows = cur.fetchall() + + materials = [] + for r in rows: + materials.append({ + 'id': r[0], + 'file_id': r[1], + 'line_number': r[2], + 'description': r[3], + 'category': r[4], + 'quantity': float(r[5]) if r[5] else 0, + 'unit': r[6] + }) + + return { + 'success': True, + 'data': materials, + 'count': len(materials) + } + + except Exception as e: + return {'error': str(e)} + diff --git a/backend/app/routers/files.py b/backend/app/routers/files.py index 8cbd861..4d9bfc1 100644 --- a/backend/app/routers/files.py +++ b/backend/app/routers/files.py @@ -299,22 +299,22 @@ async def get_materials( "limit": limit, "materials": [ { - "id": m.id, - "file_id": m.file_id, - "filename": m.original_filename, - "job_no": row.job_no, - "project_code": row.job_no, - "project_name": "Job-" + str(f.job_no) if f.job_no else "Unknown", - "original_description": row.original_description, - "quantity": float(m.quantity) if m.quantity else 0, - "unit": m.unit, - "classified_category": row.classified_category, - "classification_confidence": float(row.classification_confidence) if m.classification_confidence else 0.0, - "size_spec": m.size_spec, - "material_grade": m.material_grade, - "line_number": m.line_number, - "row_number": m.row_number, - "created_at": m.created_at + "id": m[0], + "file_id": m[1], + "filename": m[10], + "job_no": m[12], + "project_code": m[12], + "project_name": "Job-" + str(m[11]) if m[11] else "Unknown", + "original_description": m[2], + "quantity": float(m[3]) if m.quantity else 0, + "unit": m[4], + "classified_category": m[14], + "classification_confidence": float(m[15]) if m.classification_confidence else 0.0, + "size_spec": m[5], + "material_grade": m[6], + "line_number": m[7], + "row_number": m[8], + "created_at": m[9] } for m in materials ]