Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/swagger #32

Draft
wants to merge 20 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,9 @@ cython_debug/

# PyPI configuration file
.pypirc

# UV
.python-version

# vscode settings
.vscode/
200 changes: 200 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,202 @@
# hellopy-backend

hellopy-backend

## λΉ λ₯Έ μ‹œμž‘ κ°€μ΄λ“œ

```bash
# 개발 ν™˜κ²½ μ„€μ •
make setup

# DB λ§ˆμ΄κ·Έλ ˆμ΄μ…˜
make migration

# runserver (default port: 8080, host: 0.0.0.0)
make run

# runserver specific port
make run PORT=9999

# runserver localhost only
make run HOST=localhost

# run test
make test
```

## 개발 ν™˜κ²½ μ„€μ • κ°€μ΄λ“œ

```text
make setup
```

### νŒ¨ν‚€μ§€ λ§€λ‹ˆμ € μ‚¬μš©λ²•

#### κΈ€λ‘œλ²Œ λ””νŽœλ˜μ‹œ μ„€μ •

```bash
# νŒ¨ν‚€μ§€ μ„€μΉ˜ν•˜κΈ°
# uv add <package name>
> uv add django

# νŒ¨ν‚€μ§€ μ‚­μ œν•˜κΈ°
# uv remove <package name>
> uv remove django
```

#### 개발 λ””νŽœλ˜μ‹œ μ„€μ •

```bash
# νŒ¨ν‚€μ§€ μ„€μΉ˜ν•˜κΈ°
# uv add --dev <package name>
# or uv add --group dev <package name>
> uv add --dev pre-commit

# νŒ¨ν‚€μ§€ μ‚­μ œν•˜κΈ°
# uv remove --dev <package name>
# or uv add --group dev <package name>
> uv remove --dev pre-commit
```

## API μ‚¬μš© μ˜ˆμ‹œ (아직 TAGλŠ” 적용 X)

()의 경우 '()'μžμ²΄λŠ” μƒλž΅
ν•΄λ‹Ή λ‚΄μš©μ— 맞게 λ³€κ²½ν•΄μ•Όν•˜λŠ” λΆ€λΆ„
ex) (id) -> 1

### (POST) FAQ 생성
```bash
{"status":"SUCCESS","error":null,"data":{"id":2,"question":"APIλž€ λ¬΄μ—‡μΈκ°€μš”?","answer":"APIλŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜ κ°„μ˜ 톡신을 μœ„ν•œ μΈν„°νŽ˜μ΄μŠ€μž…λ‹ˆλ‹€.","is_deleted":false,"created_at":"2025-02-06T16:14:12.381235Z","updated_at":"2025-02-06T16:14:12.381272Z"}}
```
```bash
curl -X POST http://localhost:8080/api/faqs/ \
-H "Content-Type: application/json" \
-d '{
"question": "APIλž€ λ¬΄μ—‡μΈκ°€μš”?",
"answer": "APIλŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜ κ°„μ˜ 톡신을 μœ„ν•œ μΈν„°νŽ˜μ΄μŠ€μž…λ‹ˆλ‹€.",
"question_type": "activity",
"status": "normal"
}'
```

```javascript
fetch("http://localhost:8080/api/faqs/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
question: "APIλž€ λ¬΄μ—‡μΈκ°€μš”?",
answer: "APIλŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜ κ°„μ˜ 톡신을 μœ„ν•œ μΈν„°νŽ˜μ΄μŠ€μž…λ‹ˆλ‹€.",
question_type: "activity",
status: "normal"
})
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
```

### (GET) FAQ 쑰회
```bash
curl -X GET http://localhost:8080/api/faqs/
```

```javascript
fetch("http://localhost:8080/api/faqs/")
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
```

### (GET) νŠΉμ • FAQ 쑰회
- 리슀트 쑰회
```bash
curl -X GET http://localhost:8080/api/faqs/(id)/
```

```javascript
fetch("http://localhost:8080/api/faqs/2/")
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
```

- νŽ˜μ΄μ§€λ„€μ΄μ…˜
```bash
curl -X GET "http://localhost:8080/api/faqs/?page=1"
```

```javascript
fetch("http://localhost:8080/api/faqs/?page=1&page_size=10", {
method: "GET",
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
}
})
.then(response => response.json())
.then(data => {
console.log("FAQ λͺ©λ‘:", data.data);
console.log("νŽ˜μ΄μ§€λ„€μ΄μ…˜ 정보:", data.pagination);
})
.catch(error => console.error("Error fetching FAQs:", error));
```

### (PUT) FAQ μˆ˜μ •
```bash
curl -X PUT http://localhost:8080/api/faqs/(id)/ \
-H "Content-Type: application/json" \
-d '{
"question": "REST APIλž€ λ¬΄μ—‡μΈκ°€μš”?",
"answer": "REST APIλŠ” HTTPλ₯Ό 톡해 데이터λ₯Ό μ „μ†‘ν•˜λŠ” APIμž…λ‹ˆλ‹€.",
"question_type": "activity",
"status": "normal"
}'
```

```javascript
fetch("http://localhost:8080/api/faqs/(id)/", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
question: "REST APIλž€ λ¬΄μ—‡μΈκ°€μš”?",
answer: "REST APIλŠ” HTTPλ₯Ό 톡해 데이터λ₯Ό μ „μ†‘ν•˜λŠ” APIμž…λ‹ˆλ‹€."
})
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
```

### (PATCH) FAQ λΆ€λΆ„ μˆ˜μ •
```bash
curl -X PATCH http://localhost:8080/api/faqs/(id)/ \
-H "Content-Type: application/json" \
-d '{
"answer": "REST APIλŠ” ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„ κ°„μ˜ 톡신을 λ•λŠ” μΈν„°νŽ˜μ΄μŠ€μž…λ‹ˆλ‹€."
}'
```

```javascript
fetch("http://localhost:8080/api/faqs/2/", {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ answer: "REST APIλŠ” ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„ κ°„μ˜ 톡신을 λ•λŠ” μΈν„°νŽ˜μ΄μŠ€μž…λ‹ˆλ‹€." })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
```

### (DELETE) FAQ μ‚­μ œ
```bash
curl -X DELETE http://localhost:8080/api/faqs/(id)/
```

```javascript
fetch("http://localhost:8080/api/faqs/2/", {
method: "DELETE"
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
```
27 changes: 27 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
PORT=8080
HOST=0.0.0.0

setup:
uv sync
uv run src/manage.py makemigrations

migration:
uv run src/manage.py migrate

run:
uv run src/manage.py runserver $(HOST):$(PORT)

unit-test:
uv run src/manage.py test --tag=unit

feature-test:
uv run src/manage.py test --tag=feature

e2e-test:
uv run src/manage.py test --tag=e2e

test:
uv run src/manage.py test

export-swagger:
uv run src/manage.py spectacular --file swagger/api.yaml
30 changes: 23 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,42 @@
name = "hellopy-backend"
version = "0.1.0"
description = "hellopy-backend"
readme = "README.md"
requires-python = ">=3.12"
dependencies = ["django>=5.1.5", "djangorestframework>=3.15.2", "rich>=13.9.4"]

[tool.ruff]
target-version = "py312"
extend-exclude = [
"**/*.yaml", "**/.gitignore", "**/.ruff_cache/*", "**/.mypy_cache.*",
"**/assets/*", "**/.vscode/*", "**/.git/*", "**/.idea/*"
"**/*.yaml",
"**/.gitignore",
"**/.ruff_cache/*",
"**/.mypy_cache.*",
"**/__pycache__/*",
"**/assets/*",
"**/.vscode/*",
"**/.git/*",
"**/.idea/*",
"**/temp/*",
"**/*venv*/*",
]
line-length = 100
fix = true
indent-width = 4

[tool.ruff.lint]
[tool.ruff.lint]
select = ["I", "E4", "E7", "E9", "F"]
ignore = []
fixable = ["ALL"]
unfixable= []
unfixable = []

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma= false
skip-magic-trailing-comma = false
line-ending = "auto"
docstring-code-format= false
docstring-code-line-length = "dynamic"
docstring-code-format = false
docstring-code-line-length = "dynamic"

[dependency-groups]
dev = ["drf-spectacular>=0.28.0", "pre-commit>=4.1.0", "ruff>=0.9.4"]
Empty file added src/config/__init__.py
Empty file.
16 changes: 16 additions & 0 deletions src/config/asgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
ASGI config for config project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/
"""

import os

from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')

application = get_asgi_application()
Loading