L05 — standarda-template 프로젝트 폴더 한 바퀴 (popax 기준) (수정중)
standarda-template 으로 만든 프로젝트(popax)의 src/ 폴더를 열었을 때, 어떤 게 Django 앱이고 / 무엇이 프로젝트 살림이고 / .claude·credentials·scripts·utils 가 각각 무슨 역할인지 구분해서 설명할 수 있다.1. 오늘은 "프로젝트 폴더 한 바퀴"
L01 §3 에서 Django 가 앱(app) 단위로 나뉘고, 루트(설정) 앱이 따로 있다고 했다. 오늘은 거기서 한 발 더 나가, popax/src/ 를 열었을 때 보이는 모든 폴더가 뭔지 짚는다. 실제 popax/src/ 의 최상위:
popax/src/
├── popax/ ← 루트 앱 (settings·urls·wsgi) — 프로젝트 이름과 동일
├── accounts/ emails/ profiles/ projects/ sms/ ← standarda-template 기본 앱
├── meetings/ meeting_chat/ organizations/ ← popax 가 추가한 Django 앱
├── utils/ ← 앱들이 공통으로 쓰는 헬퍼 도구상자
├── credentials/ ← Google API 인증 파일 (gitignore)
├── static/ templates/ ← CSS·JS (L04) / HTML 템플릿
├── docs/ ← spec·plan·issue 등 문서 (M4 에서 다룸)
├── e2e_tests/ ← 엔드투엔드 테스트
├── .claude/ ← Claude Code 장치 (skills·agents·hooks)
├── scripts/ agent_utils/ debugging/ ← 스크립트·실험·스크래치
├── manage.py requirements.txt CLAUDE.md
└── .env .env.example .env.production .gitignore
이 뼈대(골격)는 대부분
standarda-template이 기본으로 깔아주는 것이다 (L01 §2). cookiecutter(똑같은 프로젝트 뼈대를 찍어내 주는 도구)로 새 프로젝트를 만들면accounts·utils·credentials·scripts·.claude… 가 처음부터 들어 있다. popax 는 그 위에 자기 앱(meetings등)을 얹었을 뿐이다.
2. 큰 그림 — 세 부류로 나눠 보면 안 헷갈린다
폴더가 20개쯤 돼서 처음 열면 막막하다. 하지만 새집에 이사 와 방을 용도별로 나눠 보듯, 성격으로 묶으면 세 부류다.
| 부류 | 폴더 | 한마디로 |
|---|---|---|
| ① Django 앱 | accounts emails profiles projects sms meetings meeting_chat organizations |
실제 기능(모델·뷰·URL). 화면·API 가 여기서 나온다 |
| ② 프로젝트 살림 | popax(루트 앱) · utils · static/templates · credentials · requirements.txt · .env* |
앱들이 돌아가게 받쳐주는 설정·공통도구·자원 |
| ③ 개발/에이전트 도구 | .claude · CLAUDE.md · docs · e2e_tests · scripts · agent_utils · debugging |
코드를 만들고 검증하는 쪽. 실행 자체엔 직접 안 들어감 |
오늘은 ①이 뭔지 가리는 법(§3·4), ②의 popax·utils·credentials(§5·6·7), ③의 .claude·scripts 류(§8·9)를 본다.
3. 어떤 게 Django 앱인가 — apps.py + INSTALLED_APPS
폴더만 봐선 앱인지 아닌지 모른다. 두 가지로 판별한다.
- 폴더 안에
apps.py가 있다 (+ 보통models.py,migrations/). - settings 의
INSTALLED_APPS에 등록돼 있다.
popax 의 INSTALLED_APPS (popax/settings/base.py:14):
INSTALLED_APPS = [
'django.contrib.admin', 'django.contrib.auth', ... # Django 기본 (L01 §9)
'rest_framework', 'django_extensions', # 설치한 라이브러리
'accounts.apps.AccountsConfig', # ↓ 우리 앱들
'organizations.apps.OrganizationsConfig',
'sms.apps.SmsConfig', 'emails.apps.EmailsConfig',
'profiles.apps.ProfilesConfig', 'projects.apps.ProjectsConfig',
'meetings.apps.MeetingsConfig', 'meeting_chat.apps.MeetingChatConfig',
'huey.contrib.djhuey', # 백그라운드 작업 큐
]
standarda-template기본 앱:accounts(유저·인증),profiles(프로필),projects,emails,sms. → 어느 프로젝트나 공통으로 쓰는 것들이라standarda-template에 들어 있다.- popax 가 추가한 앱:
organizations(조직),meetings(회의),meeting_chat(회의 챗봇). → popax 의 도메인 기능. INSTALLED_APPS에 올라가야 Django 가 그 앱의 모델·마이그레이션·템플릿을 인식한다. 폴더만 만든다고 앱이 되는 게 아니다.
반대로
utils,credentials,scripts,static,templates는apps.py가 없다 → Django 앱이 아니다. 그냥 폴더(파이썬 모듈/자원)일 뿐. 여기서부터 헷갈림이 풀린다.
4. 앱 폴더 내부 — 표준 구성
앱 하나를 열면 항상 비슷한 파일들이 있다. accounts/ 예:
accounts/
├── apps.py # 앱 등록 정보 (AppConfig)
├── models.py # DB 테이블 = 모델 (L02 의 \dt 로 본 그 테이블들)
├── views.py # 요청을 받아 처리하는 로직
├── urls.py # 이 앱의 URL ↔ view 연결
├── admin.py # Django admin 에 모델 노출
├── forms.py # 폼
├── api/ # DRF API (serializer·viewset)
├── migrations/ # 모델 변경 이력 (L02 다음 시간 주제)
└── tests.py
- 모델(
models.py) = 테이블. L02 에서psql로 본accounts_user가 바로 이 앱의 모델이다 (테이블 이름 =앱_모델). - 요청 흐름: URL(
urls.py) → 뷰(views.py/api/) → 모델(models.py) → 응답. 앱은 이 한 세트를 기능 단위로 묶은 것.
5. 루트 앱 popax/ — 앱이 아니라 "프로젝트 본부"
프로젝트 이름과 똑같은 popax/ 폴더는 다른 앱과 다르다. 모델이 없고 settings 가 있다 (L01 §3).
popax/
├── settings/ # base/local/production (L01·L02·L04 에서 다룬 그곳)
├── urls.py # 루트 URL — 각 앱의 urls.py 를 모은다 (ROOT_URLCONF)
├── wsgi.py # Production 서버(gunicorn)가 붙는 진입점
├── asgi.py # 비동기 진입점
└── views.py
- 여기는 기능이 아니라 "전체를 조립·설정" 하는 곳. L01 의 settings 로딩, L04 의 static 설정이 다 여기서 나왔다.
urls.py가 루트 URL 분배기다 —/accounts/...는 accounts 앱으로,/meetings/...는 meetings 앱으로 넘긴다.
6. utils/ — 앱들이 공통으로 쓰는 도구상자
utils/ 는 앱이 아니라, 어느 앱에서나 가져다(import) 쓰는 공통 도구(헬퍼) 함수 모음이다 (popax/src/utils/):
utils/
├── response_utils.py # API 응답 형식 통일
├── serializer_utils.py # DRF serializer 공통 도구
├── validator_utils.py # 입력값 검증
├── permission_utils.py # 권한 체크
├── view_utils.py # 뷰 공통 로직
├── custom_exceptions.py # 커스텀 예외
└── ...
- 같은 코드(응답 형식·검증·권한)를 앱마다 복사해 붙이지 않고 한 곳에 모아 재사용한다. 이 층의 표준 규칙은 팀 wiki 의
development/coding-conventions.md에 정리돼 있다(자습용). - 이것도
standarda-template기본 제공이라, 새 프로젝트도 처음부터 같은utils를 갖는다 (= 팀 전체가 같은 헬퍼를 쓴다, 상향평준화).
7. credentials/ — Google API 인증 파일 (커밋 금지!)
credentials/ 는 Google API 에 로그인하기 위한 인증 파일을 담는다. popax 는 Gmail·Drive·Docs 등을 쓰므로 필요하다. 파일은 두 종류:
| 파일 | 무엇 |
|---|---|
credentials.json |
Google Cloud 에서 받은 OAuth 클라이언트 비밀 (OAuth = 다른 서비스에 내 계정을 대신 열어 주는 표준 로그인 방식) (client_id·client_secret·redirect_uris) — "이 앱이 누구인지" |
token.json |
OAuth 로 실제 로그인하고 발급받은 토큰 (token·refresh_token·scopes) — "로그인된 세션" |
- 이 파일들을 standarda-core 의 Google 클라이언트가 읽는다. 경로는
.env로 지정한다 (popax/src/.env.example:44):
bash
GOOGLE_CREDENTIALS_PATH=credentials/credentials.json
GOOGLE_TOKEN_PATH=credentials/token.json
standarda-core(standarda_core/clients/auth.py)는 이 환경변수가 없으면 기본값으로 credentials/credentials.json·credentials/token.json 을 찾는다. 그래서 폴더 이름·위치가 규약으로 고정돼 있다.
- ⚠️ 절대 git 에 올리지 않는다. client_secret·refresh_token 은 그 자체가 열쇠다. .gitignore 에 credentials/ 가 통째로 들어 있다 (popax/src/.gitignore:7). → 새 서버에 배포할 땐 이 파일들을 직접 올려준다 (L01 의 .env 와 같은 원리: 비밀은 코드 밖에).
정리:
.env(L01 §6)가 API 키·비번을 담는다면,credentials/는 Google OAuth 인증 파일을 담는다. 둘 다 "비밀이라 git 밖" 이라는 점에서 같은 식구다.
8. .claude/ 와 CLAUDE.md — 에이전틱 개발 장치
.claude/ 는 Claude Code 로 개발할 때 쓰는 장치를 모은 폴더다 (앱·실행과는 무관, ③부류). popax 의 .claude/:
.claude/
├── skills/ # /develop, /dev, /release, feature-doc ... (반복 작업 자동화)
├── agents/ # spec-verifier, pdf-parser, ui-tester, merge-master ... (서브에이전트)
├── hooks/ # 커밋 전 검사 등 (check-bugfix-issue-doc.sh ...)
└── settings.json
- skills = 슬래시 명령으로 부르는 작업 절차(L03 의
/develop가 여기 있다). agents = 한 가지 일만 맡아 처리하는 에이전트(Agent)(L12). hooks = 정해진 순간에 저절로 도는 검사. → 자세한 건 M3·M4 강의에서. - 루트의
CLAUDE.md는 "이 프로젝트에서 Claude 가 지켜야 할 규칙" 문서다 (코딩 규칙·문서화 규칙 등). Claude Code 가 매 세션 자동으로 읽는다. - 이 역시 대부분
standarda-template이 깔아준다 → 모든 프로젝트가 같은 스킬·같은 규칙으로 개발된다.
9. scripts/ · agent_utils/ · debugging/ — 일회성·실험·스크래치
나머지 셋은 "본 코드는 아니고, 작업하다 생기는 것" 들이다.
scripts/: 한 번만 돌리거나 주기적으로 돌리는 스크립트와 실험. popax 엔 두 가지가 들어 있다 — 회의록을 검색용으로 바꿔 두는(임베딩) 일을 정해진 시각마다 저절로 도는 스크립트(cron,embed_minutes_cron.sh)와, 에이전트 성능 평가 실험(eval_*)이다. 앱 기능이 아니라 곁다리 자동화·검증 코드.agent_utils/: 에이전트 관련 유틸 자리(현재 popax 는__init__.py만 — 거의 비어 있음).standarda-template이 미리 잡아둔 빈 골격.debugging/: 디버깅하며 찍은 스크린샷·임시 산출물을 던져두는 스크래치 폴더..gitignore에debugging/이 있어 커밋되지 않는다 (popax/src/.gitignore:40). 안에 든 게 PNG 한 장인 이유가 이거다 — 그냥 작업 중 임시물.
구분 팁:
.gitignore에 있나 없나가 성격을 알려준다.credentials/·debugging/·.env·huey.db는 ignore → "비밀이거나 임시물". 앱·utils·.claude는 커밋됨 → "팀이 공유하는 본 코드".
오늘 정리 + 다음
- 정리:
standarda-template프로젝트의src/는 세 부류다 — ① Django 앱(accounts·meetings…apps.py+INSTALLED_APPS로 판별, 기능이 여기서 나옴), ② 프로젝트 살림(루트 앱popax/=settings·urls·wsgi,utils/=공통 헬퍼,credentials/=Google 인증,static/templates), ③ 개발 도구(.claude/=skills·agents·hooks,CLAUDE.md,scripts·debugging등). 골격 대부분은standarda-template이 깔아주고, popax 는 그 위에 자기 앱을 얹었다. - 흔한 함정: 폴더가 있다고 다 Django 앱이 아니다.
utils·credentials·scripts는 앱이 아니다(apps.py없음·INSTALLED_APPS미등록). 그리고credentials/를 실수로 커밋하면 안 된다 —client_secret·refresh_token이 노출된다 (.gitignore에 이미 들어 있으니 함부로 빼지 말 것). - 다음 시간: 앱 안으로 들어가 모델 정의 → 마이그레이션 → 실제 테이블 생성 흐름 (L02·L04 에서 예고).
- 자습 권장: 내 프로젝트
src/에서ls해보고, 각 폴더가 위 세 부류 중 어디인지 분류해보기.apps.py있는 폴더만 골라INSTALLED_APPS와 맞춰보기.