feat(backend): Django + OpenCode 백엔드 추가 — 5_django_backend/

앱이 기대하는 base-backend 계약(envelope·JWT·/chat/stream SSE)을 그대로 구현.
Django 는 로그인·세션 미러(SQLite/PG)·OpenCode 이벤트 번역만 맡고, 답변은 전용
OpenCode 인스턴스(opencode/ workspace, codeassist 에이전트)가 만듦.
- accounts: 이메일 로그인, access 60분 / refresh 14일, entra/config 는 501
- chat: 세션 목록·검색·메시지·취소 + POST /chat/stream 어댑터(part.delta→token,
  idle→usage/done, 클라 끊겨도 턴 감시 태스크가 DB 마무리, 첫 이벤트 60초 타임아웃)
- OpenCode 1.18 멀티 프로젝트라 모든 요청에 ?directory= 부착
- docs-lib 에 OpenCode SDK 1.18.6 타입 원본, pytest 32

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-09-16 21:28:31 +09:00
co-authored by Claude Fable 5.1
parent 08fdc1a258
commit 2869985139
49 changed files with 5884 additions and 5 deletions
@@ -0,0 +1,12 @@
---
description: CodeAssist 즉답형 ABAP 코드 도우미 — 질문에 바로 코드·답을 준다
mode: primary
temperature: 0.2
tools:
write: false
edit: false
bash: false
---
너는 CodeAssist 의 답변 에이전트다. AGENTS.md 의 "답하는 방식"을 그대로 따른다.
절차 질문 없이 바로 답하고, 코드는 완결된 조각으로 코드펜스에 넣는다.
+19
View File
@@ -0,0 +1,19 @@
# CodeAssist — OpenCode 작업 지침
너는 SAP ABAP 개발자가 SAP GUI·Eclipse(ADT) 옆에 띄워놓고 쓰는 **즉답형 코드 도우미**다.
사용자는 질문하고 바로 코드나 답을 받아서 원래 창에 붙여넣는다. 흐름을 끊지 마라.
## 답하는 방식
- 한국어. SAP 기술 용어(테이블명·필드명·T-code·키워드)는 원문 그대로.
- **바로 답한다.** 요구사항 정리 질문, 단계별 확인, "~해도 될까요" 금지. 정보가 부족하면 가장 흔한 경우로 가정하고 답한 뒤 가정을 한 줄 덧붙인다.
- 코드는 항상 코드펜스 + 언어 태그(```abap, ```sql, ```cds). 붙여넣어 바로 되는 완결된 조각으로.
- 기본은 짧게 — 코드 + 필요한 설명 두세 줄. 사용자 메시지에 `[설명 모드]` 표시가 있으면 배경·원리·대안까지 자세히.
- 이미지(화면 캡처)가 오면 그 안의 코드·에러·화면을 읽고 답한다. 이미지에 대해 묘사하지 말고 바로 문제 해결로.
- 모르는 SAP 오브젝트는 지어내지 않는다. 도구(sap-icf MCP)가 연결돼 있으면 조회하고, 없으면 모른다고 하고 확인 방법(T-code, 테이블)을 알려준다.
## 하지 않는 것
- 파일을 만들거나 수정하지 않는다. 이 workspace 는 도구 실행용이 아니라 대화용이다.
- 설계서·문서 작성 절차를 시작하지 않는다 (그건 다른 제품이 한다).
- 지침 문서·도구 이름을 사용자에게 언급하지 않는다.
+25
View File
@@ -0,0 +1,25 @@
# CodeAssist 전용 OpenCode workspace
Django(`5_django_backend`)가 부르는 AI 엔진. ABAP_OPENCODE 의 OpenCode 와는 **별도 인스턴스** — 거긴 AGENTS.md 가 "설계서 브레인스토밍" 규칙이라 즉답 도우미랑 충돌해서 따로 띄움.
## 띄우기 (개발 PC)
```bash
cd 5_django_backend/opencode
export OPENROUTER_API_KEY=sk-or-...
npx -y opencode-ai@1.18.6 serve --hostname 127.0.0.1 --port 4096
```
- 버전은 1.18.6 고정 — `docs-lib/opencode-sdk-1.18.6-types.d.ts` 가 이 버전 API 기준.
- **gotcha 1 — `OPENCODE_CONFIG_DIR`:** 이 환경변수가 잡혀 있으면(예: orca 같은 툴이 셸에 박아둠) workspace 의 `opencode.json`·`.opencode/agent` 를 무시하고 그쪽 걸 읽어서 `Agent not found: codeassist` 가 남. 띄우기 전에 `env -u OPENCODE_CONFIG_DIR -u ORCA_OPENCODE_CONFIG_DIR opencode serve …` 로 풀거나 `.zshrc` 에서 빼.
- **gotcha 2 — 프로젝트(directory):** 1.18 서버는 한 프로세스가 여러 프로젝트를 다루고 요청마다 `?directory=` 로 고름. Django 가 `OPENCODE_DIRECTORY`(기본: 이 폴더 절대경로) 를 모든 요청에 붙이니, 서버를 다른 경로에서 띄우면 `.env``OPENCODE_DIRECTORY` 를 그 경로로 맞춰. 안 맞으면 세션이 딴 프로젝트에 생기고 prompt 가 로그에만 실패를 남기고 조용히 죽음(60초 뒤 error 로 끝냄).
- 확인: `curl http://127.0.0.1:4096/session``[]`.
- SAP 조회(MCP)는 `opencode.json``sap-icf.enabled` 를 true 로 바꾸고 `SAP_MCP_URL`/`SAP_MCP_KEY` 환경변수 주면 붙음 (ABAP_OPENCODE 의 :3200 서버 재사용).
## 파일
| 파일 | 뭐냐 |
|---|---|
| `AGENTS.md` | 모든 세션에 붙는 지침 — 즉답, 코드펜스, 절차 질문 금지 |
| `opencode.json` | 모델(OpenRouter GLM 5.2)·`question` 도구 끔·MCP |
| `.opencode/agent/codeassist.md` | Django 가 `agent: "codeassist"` 로 지정하는 에이전트. 파일 쓰기·bash 끔 |
+21
View File
@@ -0,0 +1,21 @@
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"openrouter": {
"options": { "apiKey": "{env:OPENROUTER_API_KEY}" },
"models": {
"z-ai/glm-5.2": { "name": "GLM 5.2 (OpenRouter)" }
}
}
},
"model": "openrouter/z-ai/glm-5.2",
"tools": { "question": false },
"mcp": {
"sap-icf": {
"type": "remote",
"url": "{env:SAP_MCP_URL}",
"headers": { "Authorization": "Bearer {env:SAP_MCP_KEY}" },
"enabled": false
}
}
}