Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
58732f5
chore(web): configure Prisma
yhaeul Oct 3, 2026
350bf97
chore(web): add Prisma models from dev database
yhaeul Oct 3, 2026
bec434f
chore(web): add Prisma baseline migration
yhaeul Oct 3, 2026
579b53b
chore(web): align Prisma baseline with production schema
yhaeul Oct 10, 2026
1ac2c0f
refactor(web): add Prisma persistence mappings
yhaeul Oct 10, 2026
731cffd
refactor(web): migrate simple services to Prisma
yhaeul Oct 10, 2026
a81f8a7
refactor(web): migrate user service to Prisma
yhaeul Oct 10, 2026
6ce8108
refactor(web): migrate auth service to Prisma
yhaeul Oct 10, 2026
b21e994
refactor(web): migrate test auth service to Prisma
yhaeul Oct 10, 2026
f671c09
refactor(web): migrate review service to Prisma
yhaeul Oct 10, 2026
5940549
refactor(web): migrate search helper services to Prisma
yhaeul Oct 10, 2026
ae18464
refactor(web): migrate search queries to Prisma
yhaeul Oct 10, 2026
47cd95e
refactor(web): migrate club access and verification to Prisma
yhaeul Oct 10, 2026
ffd60db
refactor(web): migrate club manager transfer to Prisma
yhaeul Oct 10, 2026
ef25e0b
refactor(web): migrate club recruitment to Prisma
yhaeul Oct 10, 2026
3d1f9cd
refactor(web): migrate club lists and saved clubs to Prisma
yhaeul Oct 10, 2026
c98805f
refactor(web): migrate club registration to Prisma
yhaeul Oct 10, 2026
12e94f2
refactor(web): migrate club registration access and deletion to Prisma
yhaeul Oct 10, 2026
4eb0079
refactor(web): migrate club registration updates to Prisma
yhaeul Oct 10, 2026
a33136f
refactor(web): migrate club manager requests to Prisma
yhaeul Oct 10, 2026
f0edb66
refactor(web): migrate club detail reads to Prisma
yhaeul Oct 11, 2026
c43fe63
refactor(web): migrate managed club lists to Prisma
yhaeul Oct 11, 2026
63b0576
refactor(web): migrate club review summaries to Prisma
yhaeul Oct 11, 2026
1663ca6
refactor(web): complete club service Prisma migration
yhaeul Oct 11, 2026
ce8324a
refactor(web): migrate admin club reads to Prisma
yhaeul Oct 11, 2026
4a6460e
refactor(web): migrate admin club status to Prisma
yhaeul Oct 11, 2026
fb8cb83
refactor(web): migrate admin manager request status to Prisma
yhaeul Oct 11, 2026
7b37857
refactor(web): migrate admin verification status to Prisma
yhaeul Oct 11, 2026
0ca5667
refactor(web): migrate admin club histories to Prisma
yhaeul Oct 11, 2026
bc7aeb6
refactor(web): migrate admin manager request list to Prisma
yhaeul Oct 11, 2026
d3a16e6
refactor(web): migrate admin verification request list to Prisma
yhaeul Oct 11, 2026
12d8561
refactor(web): remove TypeORM connection from service provider
yhaeul Oct 11, 2026
cfcec1f
fix(web): normalize Kakao user ID for Prisma
yhaeul Oct 12, 2026
dd1c301
refactor(web): remove TypeORM after Prisma migration
yhaeul Oct 12, 2026
1c70c22
Merge branch 'develop' into refactor/prisma-orm
yhaeul Oct 12, 2026
dfbb1b0
ci(web): run Prisma migrations before production deploy
yhaeul Oct 12, 2026
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
59 changes: 59 additions & 0 deletions .github/gitops/allclear-prod-prisma-migrate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
apiVersion: batch/v1
kind: Job
metadata:
name: allclear-web-prisma-migrate
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation,HookSucceeded
spec:
backoffLimit: 0
activeDeadlineSeconds: 900
template:
metadata:
annotations:
sidecar.istio.io/inject: "false"
spec:
serviceAccountName: allclear
nodeSelector:
kubernetes.io/arch: arm64
restartPolicy: Never
containers:
- name: prisma-migrate
image: yny.ocir.io/ax1dvc8vmenm/allclear-prod/allclear-web
workingDir: /app/prisma-migrator
command:
- /app/prisma-migrator/node_modules/.bin/prisma
- migrate
- deploy
env:
- name: DB_HOST
valueFrom:
secretKeyRef:
name: allclear-prod
key: DB_HOST
- name: DB_PORT
valueFrom:
secretKeyRef:
name: allclear-prod
key: DB_PORT
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: allclear-prod
key: DB_USERNAME
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: allclear-prod
key: DB_PASSWORD
- name: DB_NAME
valueFrom:
secretKeyRef:
name: allclear-prod
key: DB_NAME
resources:
requests:
cpu: 50m
memory: 256Mi
limits:
memory: 1Gi
53 changes: 53 additions & 0 deletions .github/scripts/update-gitops-web-with-migration.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env bash
set -euo pipefail

source_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
overlay_path="${GITOPS_OVERLAY_PATH:?missing GitOps overlay path}"
image="${WEB_IMAGE:?missing web image}"
tag="${WEB_IMAGE_TAG:?missing web image tag}"
job_manifest="allclear-web-prisma-migrate.yaml"

if [[ "$overlay_path" != "argocd/allclear-prod" ]]; then
echo "This migration Job can only update the production overlay." >&2
exit 1
fi

cd "$source_root/.gitops/$overlay_path"
git config user.name 'waffle-image-update[bot]'
git config user.email '260899885+waffle-image-update[bot]@users.noreply.github.com'

for attempt in 1 2 3 4 5; do
git fetch --quiet origin main
git reset --quiet --hard origin/main

cp "$source_root/.github/gitops/allclear-prod-prisma-migrate.yaml" "$job_manifest"
if ! yq e '.resources[] | select(. == "allclear-web-prisma-migrate.yaml")' kustomization.yaml | grep -qxF "$job_manifest"; then
kustomize edit add resource "$job_manifest"
fi
kustomize edit set image "$image:$tag"

rendered="$(kustomize build .)"
job_image="$(printf '%s\n' "$rendered" | yq ea -N 'select(.kind == "Job" and .metadata.name == "allclear-web-prisma-migrate") | .spec.template.spec.containers[0].image')"
web_image="$(printf '%s\n' "$rendered" | yq ea -N 'select(.kind == "Deployment" and .metadata.name == "allclear-web") | .spec.template.spec.containers[0].image')"
if [[ "$job_image" != "$image:$tag" || "$web_image" != "$image:$tag" ]]; then
echo "The migration Job and web Deployment must render with the same image tag." >&2
exit 1
fi

git add -- kustomization.yaml "$job_manifest"
if git diff --cached --quiet; then
echo "Production GitOps image and migration Job are already up to date."
exit 0
fi

git commit --quiet -m "build: update allclear-prod/allclear-web to $tag with Prisma migration Job"
if git push --quiet origin HEAD:main; then
exit 0
fi

echo "GitOps push attempt $attempt failed; retrying on the latest main."
sleep $(( (RANDOM % 5) + 1 ))
done

echo "Could not update production GitOps after 5 attempts." >&2
exit 1
41 changes: 41 additions & 0 deletions .github/workflows/_deploy-web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ on:
description: Kustomize overlay path in waffle-world-oci
required: true
type: string
run_prisma_migrations:
description: Add a Prisma PreSync Job to the production GitOps overlay
required: false
default: false
type: boolean
secrets:
OCI_AUTH_TOKEN:
required: true
Expand Down Expand Up @@ -51,10 +56,20 @@ jobs:
--tag "$OCIR_REGISTRY/$OCIR_NAMESPACE/$OCIR_REPOSITORY:$IMAGE_TAG" \
.

- name: Validate Prisma migration runner
run: |
docker run --rm \
--platform linux/arm64 \
--workdir /app/prisma-migrator \
--entrypoint /app/prisma-migrator/node_modules/.bin/prisma \
"$OCIR_REGISTRY/$OCIR_NAMESPACE/$OCIR_REPOSITORY:$IMAGE_TAG" \
validate

- name: Push web image
run: docker push "$OCIR_REGISTRY/$OCIR_NAMESPACE/$OCIR_REPOSITORY:$IMAGE_TAG"

- name: Update GitOps image tag
if: ${{ !inputs.run_prisma_migrations }}
uses: wafflestudio/waffle-world-oci/.github/actions/update-image@main
with:
image: ${{ env.OCIR_REGISTRY }}/${{ env.OCIR_NAMESPACE }}/${{ env.OCIR_REPOSITORY }}
Expand All @@ -63,3 +78,29 @@ jobs:
# overlay is rooted at the environment directory (for example, argocd/allclear-dev).
overlay-path: ${{ inputs.gitops_overlay_path }}
private-key: ${{ secrets.DEPLOYER_APP_PRIVATE_KEY }}

- name: Generate GitOps App token
if: ${{ inputs.run_prisma_migrations }}
id: gitops-token
uses: actions/create-github-app-token@v3
with:
client-id: Iv23lijiSk5hqJhw5DsY
private-key: ${{ secrets.DEPLOYER_APP_PRIVATE_KEY }}
owner: wafflestudio
repositories: waffle-world-oci

- name: Checkout GitOps repository
if: ${{ inputs.run_prisma_migrations }}
uses: actions/checkout@v7
with:
repository: wafflestudio/waffle-world-oci
token: ${{ steps.gitops-token.outputs.token }}
path: .gitops

- name: Update production image and migration Job
if: ${{ inputs.run_prisma_migrations }}
env:
GITOPS_OVERLAY_PATH: ${{ inputs.gitops_overlay_path }}
WEB_IMAGE: ${{ env.OCIR_REGISTRY }}/${{ env.OCIR_NAMESPACE }}/${{ env.OCIR_REPOSITORY }}
WEB_IMAGE_TAG: ${{ env.IMAGE_TAG }}
run: bash .github/scripts/update-gitops-web-with-migration.sh
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ jobs:
- name: Setup Node environment
uses: ./.github/actions/setup-node-env

- name: Generate Prisma client
run: pnpm --filter allclear-web prisma:generate

- name: Lint, typecheck, and test
run: pnpm verify

Expand All @@ -53,6 +56,9 @@ jobs:
- name: Setup Node environment
uses: ./.github/actions/setup-node-env

- name: Generate Prisma client
run: pnpm --filter allclear-web prisma:generate

- name: Build web
run: pnpm --filter allclear-web build

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/deploy-web-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
types: [closed]
paths:
- apps/web/**
- apps/web-migrator/**
- package.json
- pnpm-lock.yaml
- pnpm-workspace.yaml
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/deploy-web-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
types: [closed]
paths:
- apps/web/**
- apps/web-migrator/**
- package.json
- pnpm-lock.yaml
- pnpm-workspace.yaml
Expand All @@ -14,6 +15,8 @@ on:
- .dockerignore
- .github/workflows/_deploy-web.yml
- .github/workflows/deploy-web-prod.yml
- .github/gitops/allclear-prod-prisma-migrate.yaml
- .github/scripts/update-gitops-web-with-migration.sh

jobs:
deploy:
Expand All @@ -22,6 +25,7 @@ jobs:
with:
ocir_repository: allclear-prod/allclear-web
gitops_overlay_path: argocd/allclear-prod
run_prisma_migrations: true
secrets:
OCI_AUTH_TOKEN: ${{ secrets.OCI_AUTH_TOKEN }}
DEPLOYER_APP_PRIVATE_KEY: ${{ secrets.DEPLOYER_APP_PRIVATE_KEY }}
51 changes: 51 additions & 0 deletions .github/workflows/verify-web-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Verify web image

on:
pull_request:
branches: [develop, main]
paths:
- apps/web/**
- apps/web-migrator/**
- package.json
- pnpm-lock.yaml
- pnpm-workspace.yaml
- turbo.json
- biome.json
- .dockerignore
- .github/workflows/_deploy-web.yml
- .github/workflows/deploy-web-prod.yml
- .github/gitops/allclear-prod-prisma-migrate.yaml
- .github/scripts/update-gitops-web-with-migration.sh
- .github/workflows/verify-web-image.yml

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
build-and-validate:
runs-on: ubuntu-24.04-arm

steps:
- name: Checkout
uses: actions/checkout@v5.0.1

- name: Build ARM64 web image
run: |
docker build \
--file apps/web/Dockerfile \
--platform linux/arm64 \
--tag allclear-web:prisma-verify \
.

- name: Validate Prisma migration runner
run: |
docker run --rm \
--platform linux/arm64 \
--workdir /app/prisma-migrator \
--entrypoint /app/prisma-migrator/node_modules/.bin/prisma \
allclear-web:prisma-verify \
validate
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ pnpm android:debug

환경 변수 파일은 저장소에 포함하지 않습니다. 각 앱의 `.env.example`을 복사해 로컬 환경에 맞게 설정하세요.

웹 서버는 Prisma Client로 PostgreSQL에 연결합니다. 의존성을 설치한 직후나
`apps/web/prisma/schema.prisma`를 변경한 뒤에는 저장소 루트에서
`pnpm --dir apps/web prisma:generate`를 실행하세요. 평소에는 생성된 Client가 있으면
`pnpm dev:web`만 실행하면 됩니다. 웹 빌드는 Client를 자동 생성하며, Client 생성은
DB 스키마를 변경하지 않습니다. DB 변경은 별도의 Prisma migration으로 관리합니다.

## 검사

```bash
Expand Down
9 changes: 9 additions & 0 deletions apps/web-migrator/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "allclear-web-migrator",
"version": "1.0.0",
"private": true,
"dependencies": {
"dotenv": "16.6.1",
"prisma": "7.10.0"
}
}
5 changes: 4 additions & 1 deletion apps/web/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -296,4 +296,7 @@ oci-migration.md
oci-vault-secrets.md


.codex
.codex

# Prisma Client is generated during build and CI.
server/infra/database/generated/prisma/
18 changes: 18 additions & 0 deletions apps/web/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,20 @@ WORKDIR /app
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY apps/mobile/package.json ./apps/mobile/package.json
COPY apps/web/package.json ./apps/web/package.json
COPY apps/web-migrator/package.json ./apps/web-migrator/package.json
RUN pnpm install --frozen-lockfile

# --- Prisma migration tools ---
FROM base AS migrator
WORKDIR /app
RUN apk add --no-cache openssl
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY apps/mobile/package.json ./apps/mobile/package.json
COPY apps/web/package.json ./apps/web/package.json
COPY apps/web-migrator/package.json ./apps/web-migrator/package.json
RUN pnpm --filter allclear-web-migrator install --frozen-lockfile
RUN pnpm --filter allclear-web-migrator deploy --prod --legacy /prisma-migrator

# --- Build ---
FROM base AS builder
WORKDIR /app
Expand All @@ -35,12 +47,18 @@ ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
ENV HOSTNAME=0.0.0.0

RUN apk add --no-cache openssl

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static
COPY --from=migrator --chown=nextjs:nodejs /prisma-migrator ./prisma-migrator
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/prisma ./prisma-migrator/prisma
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/prisma.config.ts ./prisma-migrator/prisma.config.ts
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/server/infra/database/prisma-url.ts ./prisma-migrator/server/infra/database/prisma-url.ts

USER nextjs

Expand Down
12 changes: 8 additions & 4 deletions apps/web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@
## 처음 프로젝트 환경 셋업하기

```Bash
git clone https://github.com/pado-corp/clubhouse-web.git
cd clubhouse-web
git clone https://github.com/wafflestudio/allclear.git
cd allclear
pnpm install
pnpm husky install
pnpm dev
pnpm --dir apps/web prisma:generate
pnpm dev:web
```

위 명령은 저장소 루트에서 실행합니다. 이후에는 Prisma 스키마가 바뀌거나
`node_modules`를 다시 설치한 경우에만 `prisma:generate`를 다시 실행하면 됩니다.
`pnpm dev:web`은 DB migration을 실행하지 않습니다.

## 기술 스택

### 언어 / 프레임워크
Expand Down
Loading
Loading