📚 엔지니어 · 세션 · 프로젝트 이해 (수정중) · L04

L05 — standarda-template 프로젝트 폴더 한 바퀴 (popax 기준) (수정중)

작성일자 2026-06-18  ·  수정일자 2026-06-18  ·  강의차수 L04  ·  예상소요 30분

목표 이 강의가 끝나면 학습자가 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

폴더만 봐선 앱인지 아닌지 모른다. 두 가지로 판별한다.

  1. 폴더 안에 apps.py 가 있다 (+ 보통 models.py, migrations/).
  2. 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 와 맞춰보기.
이 강의를 학습하셨나요?