-
[16] 개발 - 5/28 수정 사항 14학년/Project-itda 2025. 5. 28. 18:05
안냐쎼요
하 글쓰기 진짜 진심 귀찮네
그치만 이거 써놓으니까 과거에 했던거 봐야할 때 유용하긴해서;;;
설명좀적게하고 변경사항만이라도 적어볼게요
1. 수정된 db에맞춰 공지 가져오기 수정
성공띠 나머지는 그대로고
fetch에서 에러나는부분을 좀 수정했고 , 요청에서 project_id를 Pg_id로 바꾸었어요
api에선 await추가하라해서 추가했구요(왜인지는모룸 저번엔 없어도 잘됐는데...)
2.1 투두 api 갈아엎기
기존에는 너무 중복되는기능도많고 잘게쪼개져있어서 하나로 합쳤어요
# 투두 생성 API@app.post("/todos", response_model=Todo)async def create_todo(todo: TodoCreate):todo_id = str(uuid.uuid4())
# 상태 유효성 검사if todo.status not in VALID_STATUSES:raise HTTPException(status_code=400, detail="Invalid status")
# DB에 저장new_todo = await Todo.objects.create(id=todo_id,text=todo.text,user={"id": todo.user_id},deadline=todo.deadline,start_day=todo.start_day)
# Redis 저장await r.sadd(f"project:{todo.project_id}:todos", todo_id)await r.set(f"todo_status:{todo_id}", todo.status)
return new_todo
@app.get("/todos")async def get_all_todos():todos = await Todo.objects.all()return todos@app.get("/projects/{project_id}/todos/status/{status}")async def filltering_status_todo(project_id: str, status: str):if status not in VALID_STATUSES:raise HTTPException(status_code=400, detail="Invalid status")result = []keys = await r.keys("project:*:todos") # ✅ await 추가for key in keys:if key == f"project:{project_id}:todos":todo_ids = await r.smembers(key) # 여기도 await 필요for todo_id in todo_ids:status_value = await r.get(f"todo_status:{todo_id}")if status_value:status_str = status_value.decode("utf-8") if isinstance(status_value, bytes) else status_valueif status_str == status:result.append(todo_id.decode("utf-8") if isinstance(todo_id, bytes) else todo_id)
return {"status": status, "todos": result}
# 투두 프로젝트 별 가져오기 api@app.get("/projects/{project_id}/todos", response_model=List[TodoResponse])async def get_todos_by_project(project_id: str):print("요청된 project_id:", project_id)keys = await r.keys("*")print("현재 Redis에 저장된 키 목록:", keys)
todo_ids = await r.smembers(f"project:{project_id}:todos")print("조회된 투두 ID 목록:", todo_ids)
result = []for todo_id in todo_ids:todo = await Todo.objects.get_or_none(id=todo_id)if todo:status = await r.get(f"todo_status:{todo_id}") or "in_progress"result.append(TodoResponse(id=todo.id,text=todo.text,user_id=todo.user.id,deadline=str(todo.deadline),start_day=str(todo.start_day),project_id=project_id,status=status))return result
# 투두 삭제 API@app.delete("/todos/{todo_id}")async def delete_todo(todo_id: str, project_id: str):todo = await Todo.objects.get_or_none(id=todo_id)if not todo:raise HTTPException(status_code=404, detail="Todo not found")
await todo.delete()
await r.delete(f"todo_status:{todo_id}")await r.srem(f"project:{project_id}:todos", todo_id)
return {"message": f"{todo_id} deleted successfully"}디비 업뎃이랑 레디스 업뎃이 따로길래, 이것도 수정했어요
이제 create할때 status...project....이런거신경안ㅅ고
/todo로만하면돼요
그리고 이것도 await추가하라길래..했네요
스키마도 status추가해줘요
이거없어서 따로 api를 받아줬었거든요
2.2 todo Status 프론트수정
ㅇㅇ 제곧내
api바꾼거에 맞춰서 request url수정하고
2.3 todo 가져오기 수정
이것도 프론트에선
inProgress라쓰는데
백에선 in_progress라써서....(변수명통일의 중요성)
네 ...수정했네요
2.4 todo 삭제수정체크 handle url수정
if (!todos[status]) return;const updatedData = {text: localEditContent,user_id: username,deadline: localEditDueDate.includes('.')? localEditDueDate.replaceAll('.', '-'): localEditDueDate,start_day: '2025-04-01',project_id: Pg_id,};try {const response = await fetch(`http://127.0.0.1:8008/todos/${id}`, {method: "PUT",headers: { "Content-Type": "application/json" },body: JSON.stringify(updatedData),});if (!response.ok) throw new Error("세이브에딧함수 ㅉㅉㅉㅉ");setTodos((prevTodos) => ({...prevTodos,[status]: prevTodos[status].map((item) =>item.id === id ? { ...item, content: localEditContent, dueDate: updatedData.deadline } : item),}));setEditingId(null);} catch (error) {console.error("세이브에딧ㅉㅉㅉㅉㅉ", error);}};이것도 api바뀌었기에 request url수정해줘요
삭체크코드 생략띠요.
3.피그마 필요 페이지 ui제작
이것도 하다보니까
지원하기를 어디서 받고,
지원하기를 하는데 모집자입장에선 그래도 최소한의 자기소개나, 역할군어디에 지원하는지 알아야하잖아요
그게없이걍 지원하기만 넣어서...
팝업 하나 만들었어요
db도만들어야하는데 이건 팀원이 제작하면서 만드는게 나을것같아서 ui만 만들었네요
인생은 카피와 복붙의 연속이다.예외
건강한 멘탈건강을 위해 파이프 게임으로 머리도 비워줍니다.
(중요)
4. 폴더로직 수정
잘되던 폴더가 또 안돼요
하이래서 디비를 처음에 잘짜야함
디비 다른사람이 바꾸니까 영향 오는게 ㅈㄴ많음
우선 지금 코드부터 다시 긁어와볼게요
아래는 api예요 ㅈㄴ많네요;
# ───────────── 플젝-피드백-업로드 파일 crud ───────────── #from .s3 import s3, BUCKET_NAMEimport uuidfrom fastapi import UploadFile, File#객체조회@app.get("/projects/{project_id}/files")async def get_project_files(project_id: int):files = await UploadedFile.objects.filter(project__id=project_id).all()return [{"id": f.id,"key": f.s3_key,"url": f.s3_url,"name": f.name,"uploaded_at": f.uploaded_at.isoformat(),"size": f.size,"folder_id": f.folder.id if f.folder else None,"uploader": {"id": f.uploader.id} if f.uploader else None, }for f in files]
from datetime import datetime
#s3에 업로드 apifrom fastapi import Form@app.post("/upload/s3/{project_id}")async def upload_s3(project_id: int,file: UploadFile = File(...),folder_id: int = Form(None),uploader: str = Form(...)):file_content = await file.read()extension = file.filename.split('.')[-1]s3_key = f"uploads/{uuid.uuid4()}.{extension}"
s3.put_object(Bucket=BUCKET_NAME,Key=s3_key,Body=file_content,ContentType=file.content_type)
s3_url = f"https://{BUCKET_NAME}.s3.amazonaws.com/{s3_key}"
project = await ProjectInfo.objects.get(id=project_id)folder = await ProjectFolder.objects.get(id=folder_id) if folder_id else None
saved = await UploadedFile.objects.create(name=file.filename,s3_key=s3_key,s3_url=s3_url,size=len(file_content),project=project,folder=folder,uploader=uploader,&l아자꾸자동저장이안되냐
세번이나 같은 글 쓰긴 좀그러니까 뭐했냐면
aws key랑 시크릿키유출의심된다고 iam막혀서 그거다시 유저 만들었구요
그랬더니 삭제가되더라구요. 다음거에서 타임라인올릴게요 그러면 대시보드는 끝날듯 ?
야호~
728x90'4학년 > Project-itda' 카테고리의 다른 글
[18] 개발 - 무한 모델추가 츠쿠요미18] 개발 - 무한 모델추가 츠쿠요미 (0) 2025.06.03 [17] 개발 - 5/29 수정 사항 2 ( 수정중 (0) 2025.05.29 [15] 개발 - 중간 머지 ! (0) 2025.05.28 [Front] React-ccalendar-timeline API사용법 - 폐기 (0) 2025.05.23 [14] 보고서 - 중간보고서 (0) 2025.05.23