Skip to content

Commit

Permalink
Merge pull request #195 from DNDACADEMY/develop
Browse files Browse the repository at this point in the history
fix: vercel blob cache issue로 최신 데이터 업데이트가 안되는 이슈 수정
  • Loading branch information
saseungmin authored Sep 25, 2024
2 parents c4eff31 + c3bbd83 commit 4a2ae58
Show file tree
Hide file tree
Showing 27 changed files with 358 additions and 161 deletions.
44 changes: 22 additions & 22 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,6 @@ jobs:
path: ${{ needs.job_install_dependencies.outputs.yarn_cache_dir_path }}
key: ${{ needs.job_install_dependencies.outputs.dependency_cache_key }}

- name: Compute @dnd-academy/ui cache key
id: compute_ui_cache_key
run: echo "hash=${{ runner.os }}-ui-build-${{ hashFiles('packages/ui/**') }}" >> $GITHUB_OUTPUT

- name: Check @dnd-academy/ui build cache
uses: actions/cache@v4
id: cache_built_ui_packages
with:
path: ${{ env.CACHED_BUILD_PACKAGE_UI_PATHS }}
key: ${{ steps.compute_ui_cache_key.outputs.hash }}

- name: Build @dnd-academy/ui
if: steps.cache_built_ui_packages.outputs.cache-hit != 'true'
run: yarn workspace @dnd-academy/ui build

- name: Compute @dnd-academy/core cache key
id: compute_core_cache_key
run: echo "hash=${{ runner.os }}-core-build-${{ hashFiles('packages/core/**') }}" >> $GITHUB_OUTPUT
Expand All @@ -111,11 +96,26 @@ jobs:
if: steps.cache_built_core_packages.outputs.cache-hit != 'true'
run: yarn workspace @dnd-academy/core build

- name: Compute @dnd-academy/ui cache key
id: compute_ui_cache_key
run: echo "hash=${{ runner.os }}-ui-build-${{ hashFiles('packages/ui/**') }}" >> $GITHUB_OUTPUT

- name: Check @dnd-academy/ui build cache
uses: actions/cache@v4
id: cache_built_ui_packages
with:
path: ${{ env.CACHED_BUILD_PACKAGE_UI_PATHS }}
key: ${{ steps.compute_ui_cache_key.outputs.hash }}

- name: Build @dnd-academy/ui
if: steps.cache_built_ui_packages.outputs.cache-hit != 'true'
run: yarn workspace @dnd-academy/ui build

outputs:
dependency_cache_key: ${{ needs.job_install_dependencies.outputs.dependency_cache_key }}
yarn_cache_dir_path: ${{ needs.job_install_dependencies.outputs.yarn_cache_dir_path }}
build_package_ui_cache_key: ${{ steps.compute_ui_cache_key.outputs.hash }}
build_package_core_cache_key: ${{ steps.compute_core_cache_key.outputs.hash }}
build_package_ui_cache_key: ${{ steps.compute_ui_cache_key.outputs.hash }}

# continuous-integration:
# needs: [job_packages_build]
Expand Down Expand Up @@ -168,18 +168,18 @@ jobs:
path: ${{ needs.job_packages_build.outputs.yarn_cache_dir_path }}
key: ${{ needs.job_packages_build.outputs.dependency_cache_key }}

- name: Check build ui package cache
uses: actions/cache@v4
with:
path: ${{ env.CACHED_BUILD_PACKAGE_UI_PATHS }}
key: ${{ needs.job_packages_build.outputs.build_package_ui_cache_key }}

- name: Check build core package cache
uses: actions/cache@v4
with:
path: ${{ env.CACHED_BUILD_PACKAGE_CORE_PATHS }}
key: ${{ needs.job_packages_build.outputs.build_package_core_cache_key }}

- name: Check build ui package cache
uses: actions/cache@v4
with:
path: ${{ env.CACHED_BUILD_PACKAGE_UI_PATHS }}
key: ${{ needs.job_packages_build.outputs.build_package_ui_cache_key }}

- name: Publish Project to Chromatic
uses: chromaui/action@latest
with:
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion apps/admin/@types/environment.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace NodeJS {
AUTH_GOOGLE_ID: string;
AUTH_GOOGLE_SECRET: string;
ALLOWED_EMAIL_ADDRESSES: string;
DND_ACADEMY_V2_BLOB_READ_WRITE_TOKEN: string;
BLOB_READ_WRITE_TOKEN: string;
GOOGLE_CLIENT_EMAIL: string;
GOOGLE_PRIVATE_KEY: string;
CRON_SECRET: string;
Expand Down
4 changes: 2 additions & 2 deletions apps/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@
"framer-motion": "11.2.10",
"google-auth-library": "9.13.0",
"google-spreadsheet": "4.1.2",
"next": "14.2.4",
"next": "14.2.12",
"next-auth": "5.0.0-beta.19",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-perfect-scrollbar": "1.5.8"
},
"devDependencies": {
"@dnd-academy/eslint-config": "*",
"@next/eslint-plugin-next": "14.2.4",
"@next/eslint-plugin-next": "14.2.12",
"@testing-library/dom": "10.3.1",
"@testing-library/jest-dom": "6.4.6",
"@testing-library/react": "16.0.0",
Expand Down
1 change: 0 additions & 1 deletion apps/admin/src/actions/count.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ export async function totalCountStatusAction(
await put('total_count_status.json', requestBlob, {
access: 'public',
token: process.env.DND_ACADEMY_V2_BLOB_READ_WRITE_TOKEN,
addRandomSuffix: false,
});

await revalidateWebPath(['/', '/dnd/about']);
Expand Down
46 changes: 46 additions & 0 deletions apps/admin/src/app/api/blob/latest/[name]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { NextRequest, NextResponse } from 'next/server';

import { api, ApiError, getLatestItemReduce } from '@dnd-academy/core';
import { list } from '@vercel/blob';

// eslint-disable-next-line import/prefer-default-export
export async function GET(_: NextRequest, { params }: { params: { name: string } }) {
if (!params?.name) {
return NextResponse.json(null, {
status: 400,
statusText: 'Missing name parameter',
});
}

const { blobs } = await list({
prefix: params.name,
token: process.env.BLOB_READ_WRITE_TOKEN,
});

const blob = getLatestItemReduce(blobs);

try {
const responseBlobData = await api({
url: blob.url,
method: 'GET',
});

return Response.json(responseBlobData);
} catch (error) {
if (error instanceof ApiError) {
return NextResponse.json({
error: error.message,
}, {
status: error.status,
statusText: error.message,
});
}

return NextResponse.json({
error: 'Internal Server Error',
}, {
status: 500,
statusText: 'Internal Server Error',
});
}
}
4 changes: 1 addition & 3 deletions apps/admin/src/app/api/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ export const updateCurrentApplicantCount = async () => {

await put('current_applicant_count.json', requestBlob, {
access: 'public',
token: process.env.DND_ACADEMY_V2_BLOB_READ_WRITE_TOKEN,
addRandomSuffix: false,
cacheControlMaxAge: 3600,
token: process.env.BLOB_READ_WRITE_TOKEN,
});

return currentApplicantCountForm;
Expand Down
22 changes: 12 additions & 10 deletions apps/admin/src/app/current-applicant-count/page.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { api, type CurrentApplicantCount } from '@dnd-academy/core';
import { CurrentApplicantCount } from '@dnd-academy/core';
import { Counter, PageTitle } from '@dnd-academy/ui';
import { withServerErrorBoundary } from '@dnd-academy/ui/server';

import CurrentApplicantCountAction from '@/components/CurrentApplicantCountAction';

import styles from './page.module.scss';

async function page() {
const currentApplicantCountData = await api<CurrentApplicantCount>({
url: '/current_applicant_count.json',
method: 'GET',
});
type Props = {
data: CurrentApplicantCount;
};

const currentApplicantCount = currentApplicantCountData.designer
+ currentApplicantCountData.developer;
async function Page({ data }: Props) {
const { designer, developer } = data;

return (
<>
Expand All @@ -22,7 +21,7 @@ async function page() {
/>
<div className={styles.counter}>
오늘까지&nbsp;
<Counter count={currentApplicantCount} />
<Counter count={designer + developer} />
명이 지원했어요!
</div>
<CurrentApplicantCountAction />
Expand All @@ -33,4 +32,7 @@ async function page() {
);
}

export default page;
export default withServerErrorBoundary(Page, {
url: '/blob/latest/current_applicant_count',
type: 'bff',
});
2 changes: 1 addition & 1 deletion apps/admin/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Navigator from '@/components/Navigator';
async function MainPage() {
const session = await auth();

if (!session) {
if (!session && process.env.NODE_ENV === 'production') {
redirect('/login');
}

Expand Down
24 changes: 15 additions & 9 deletions apps/admin/src/app/total-count-status/page.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { api, type TotalCountStatus } from '@dnd-academy/core';
import { type TotalCountStatus } from '@dnd-academy/core';
import { CounterCard, PageTitle } from '@dnd-academy/ui';
import { withServerErrorBoundary } from '@dnd-academy/ui/server';

import TotalCountStatusForm from '@/components/TotalCountStatusForm';

import styles from './page.module.scss';

async function page() {
const totalCountStatus = await api<TotalCountStatus>({
url: '/total_count_status.json',
method: 'GET',
});
type Props = {
data: TotalCountStatus;
};

async function Page({ data }: Props) {
const {
cumulativeApplicants, dropouts, totalParticipants, totalProjects,
} = totalCountStatus;
} = data;

return (
<>
Expand All @@ -27,9 +27,15 @@ async function page() {
<CounterCard count={totalProjects} title="총 프로젝트 수" suffix="개" />
<CounterCard count={dropouts} title="이탈자 수" color="primary" />
</div>
<TotalCountStatusForm initialTotalCountStatus={totalCountStatus} />
<TotalCountStatusForm initialTotalCountStatus={{
cumulativeApplicants, totalParticipants, totalProjects, dropouts,
}}
/>
</>
);
}

export default page;
export default withServerErrorBoundary(Page, {
url: '/blob/latest/total_count_status',
type: 'bff',
});
2 changes: 1 addition & 1 deletion apps/admin/src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { auth as middleware } from '@/auth';
import { isEmailAllowed } from '@/utils';

export default middleware((req) => {
if (req.nextUrl.pathname === '/login') {
if (req.nextUrl.pathname === '/login' || process.env.NODE_ENV === 'development') {
return NextResponse.next({
request: req,
});
Expand Down
1 change: 1 addition & 0 deletions apps/web/@types/environment.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace NodeJS {
NEXT_PUBLIC_VERCEL_BLOB_HOST: string;
NEXT_PUBLIC_GA_MEASUREMENT_ID: string;
NEXT_PUBLIC_CHANNEL_IO_PLUGIN_KEY: string;
DND_ACADEMY_V2_BLOB_READ_WRITE_TOKEN: string;
REVALIDATION_TOKEN: string;
ADMIN_ORIGIN: string;
}
Expand Down
2 changes: 1 addition & 1 deletion apps/web/next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
7 changes: 4 additions & 3 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@
"@channel.io/channel-web-sdk-loader": "1.1.7",
"@dnd-academy/core": "*",
"@dnd-academy/ui": "*",
"@next/third-parties": "14.2.4",
"@next/third-parties": "14.2.12",
"@vercel/blob": "0.23.4",
"clsx": "2.1.1",
"dayjs": "1.11.11",
"framer-motion": "11.2.10",
"next": "14.2.4",
"next": "14.2.12",
"qs": "6.12.1",
"react": "18.3.1",
"react-countup": "6.5.3",
Expand All @@ -54,7 +55,7 @@
"devDependencies": {
"@chromatic-com/storybook": "1.6.1",
"@dnd-academy/eslint-config": "*",
"@next/eslint-plugin-next": "14.2.4",
"@next/eslint-plugin-next": "14.2.12",
"@storybook/addon-essentials": "8.2.1",
"@storybook/addon-interactions": "8.2.1",
"@storybook/addon-links": "8.2.1",
Expand Down
46 changes: 46 additions & 0 deletions apps/web/src/app/api/blob/latest/[name]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { NextRequest, NextResponse } from 'next/server';

import { api, ApiError, getLatestItemReduce } from '@dnd-academy/core';
import { list } from '@vercel/blob';

// eslint-disable-next-line import/prefer-default-export
export async function GET(_: NextRequest, { params }: { params: { name: string } }) {
if (!params?.name) {
return NextResponse.json(null, {
status: 400,
statusText: 'Missing name parameter',
});
}

const { blobs } = await list({
prefix: params.name,
token: process.env.DND_ACADEMY_V2_BLOB_READ_WRITE_TOKEN,
});

const blob = getLatestItemReduce(blobs);

try {
const responseBlobData = await api({
url: blob.url,
method: 'GET',
});

return Response.json(responseBlobData);
} catch (error) {
if (error instanceof ApiError) {
return NextResponse.json({
error: error.message,
}, {
status: error.status,
statusText: error.message,
});
}

return NextResponse.json({
error: 'Internal Server Error',
}, {
status: 500,
statusText: 'Internal Server Error',
});
}
}
28 changes: 18 additions & 10 deletions apps/web/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { api, type CurrentApplicantCount, type FAQ } from '@dnd-academy/core';
import { notFound } from 'next/navigation';

import {
api, type CurrentApplicantCount, type FAQ, serverErrorHandling,
} from '@dnd-academy/core';

import HomePage from '@/components/pages/HomePage';
import { getEventStatus } from '@/lib/apis/event';
Expand All @@ -14,15 +18,19 @@ type Props = {
};

async function Home({ searchParams }: Props) {
const currentApplicantCountData = await api<CurrentApplicantCount>({
url: '/current_applicant_count.json',
method: 'GET',
});

const faqData = await api<FAQ[]>({
url: '/faq.json',
method: 'GET',
});
const currentApplicantCountData = await serverErrorHandling(() => api<CurrentApplicantCount>({
url: '/blob/latest/current_applicant_count',
type: 'bff',
}));

const faqData = await serverErrorHandling(() => api<FAQ[]>({
url: '/blob/latest/faq',
type: 'bff',
}));

if (!currentApplicantCountData || !faqData) {
notFound();
}

const currentApplicantCount = checkNumber(currentApplicantCountData?.designer)
+ checkNumber(currentApplicantCountData?.developer);
Expand Down
Loading

0 comments on commit 4a2ae58

Please sign in to comment.