From 1a96e5eef60a8f7cb3181a151ab1f74c08b41ac5 Mon Sep 17 00:00:00 2001 From: DaX Date: Thu, 19 Jun 2025 01:13:15 +0200 Subject: [PATCH] Switch to static export with build-time data fetching - Change from server-side rendering to static export - Fetch data at build time and save as JSON - Remove API routes and tests, use static JSON file - Switch back to WEB platform from WEB_COMPUTE - Update build test for static export - Exclude out directory from security scan - Much simpler and more reliable approach --- amplify.yml | 5 ++--- app/api/filaments/route.ts | 39 -------------------------------------- app/page.tsx | 2 +- next.config.js | 2 +- scripts/fetch-data.js | 36 +++++++++++++++++++++++++++++++++++ scripts/security-check.js | 1 + scripts/test-build.js | 23 +--------------------- terraform/main.tf | 2 +- 8 files changed, 43 insertions(+), 67 deletions(-) delete mode 100644 app/api/filaments/route.ts create mode 100644 scripts/fetch-data.js diff --git a/amplify.yml b/amplify.yml index d910215..91617a9 100644 --- a/amplify.yml +++ b/amplify.yml @@ -9,11 +9,10 @@ frontend: - env | grep CONFLUENCE | sed 's/=.*/=***/' build: commands: + - npx tsx scripts/fetch-data.js - npm run build - - cp -r .next/static .next/standalone/.next/ - - cp .next/standalone/.next/required-server-files.json .next/standalone/ artifacts: - baseDirectory: .next/standalone + baseDirectory: out files: - '**/*' cache: diff --git a/app/api/filaments/route.ts b/app/api/filaments/route.ts deleted file mode 100644 index 5dc122c..0000000 --- a/app/api/filaments/route.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { NextResponse } from 'next/server'; -import { fetchFromConfluence } from '../../../src/server/confluence'; - -export const runtime = 'nodejs'; - -export async function GET() { - try { - // Get environment variables from server-side only - const env = { - CONFLUENCE_API_URL: process.env.CONFLUENCE_API_URL, - CONFLUENCE_TOKEN: process.env.CONFLUENCE_TOKEN, - CONFLUENCE_PAGE_ID: process.env.CONFLUENCE_PAGE_ID, - }; - - // Validate environment variables - if (!env.CONFLUENCE_API_URL || !env.CONFLUENCE_TOKEN || !env.CONFLUENCE_PAGE_ID) { - console.error('Missing Confluence environment variables'); - return NextResponse.json( - { error: 'Server configuration error' }, - { status: 500 } - ); - } - - const filaments = await fetchFromConfluence(env); - - return NextResponse.json(filaments, { - headers: { - 'Cache-Control': 'public, s-maxage=300, stale-while-revalidate=600', - }, - }); - } catch (error) { - console.error('API Error:', error); - // Never expose internal error details to client - return NextResponse.json( - { error: 'Failed to fetch filaments' }, - { status: 500 } - ); - } -} \ No newline at end of file diff --git a/app/page.tsx b/app/page.tsx index 1375f61..e175831 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -34,7 +34,7 @@ export default function Home() { setLoading(true); setError(null); - const response = await axios.get('/api/filaments'); + const response = await axios.get('/data.json'); setFilaments(response.data); setLastUpdate(new Date()); } catch (err) { diff --git a/next.config.js b/next.config.js index 61eb67e..19f7f54 100644 --- a/next.config.js +++ b/next.config.js @@ -1,7 +1,7 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, - output: 'standalone', + output: 'export', } module.exports = nextConfig \ No newline at end of file diff --git a/scripts/fetch-data.js b/scripts/fetch-data.js new file mode 100644 index 0000000..f558eb6 --- /dev/null +++ b/scripts/fetch-data.js @@ -0,0 +1,36 @@ +const fs = require('fs'); +const path = require('path'); +const { fetchFromConfluence } = require('../src/server/confluence.ts'); + +async function fetchData() { + console.log('Fetching data from Confluence...'); + + const env = { + CONFLUENCE_API_URL: process.env.CONFLUENCE_API_URL, + CONFLUENCE_TOKEN: process.env.CONFLUENCE_TOKEN, + CONFLUENCE_PAGE_ID: process.env.CONFLUENCE_PAGE_ID + }; + + try { + const data = await fetchFromConfluence(env); + + // Create public directory if it doesn't exist + const publicDir = path.join(__dirname, '..', 'public'); + if (!fs.existsSync(publicDir)) { + fs.mkdirSync(publicDir, { recursive: true }); + } + + // Write data to public directory + fs.writeFileSync( + path.join(publicDir, 'data.json'), + JSON.stringify(data, null, 2) + ); + + console.log(`āœ… Fetched ${data.length} filaments`); + } catch (error) { + console.error('āŒ Failed to fetch data:', error.message); + process.exit(1); + } +} + +fetchData(); \ No newline at end of file diff --git a/scripts/security-check.js b/scripts/security-check.js index 002cb4f..8b798f3 100644 --- a/scripts/security-check.js +++ b/scripts/security-check.js @@ -18,6 +18,7 @@ const excludePatterns = [ /\.next/, /dist/, /build/, + /out/, /terraform\.tfvars$/, /\.env/, /security-check\.js$/, diff --git a/scripts/test-build.js b/scripts/test-build.js index ac76fc7..df24fbf 100755 --- a/scripts/test-build.js +++ b/scripts/test-build.js @@ -26,8 +26,7 @@ try { // Check for required files console.log('\nšŸ” Checking build output...'); const checks = [ - { path: '.next/standalone/server.js', name: 'Standalone server' }, - { path: '.next/standalone/.next/required-server-files.json', name: 'Required server files' }, + { path: 'out/index.html', name: 'Static HTML output' }, { path: '.next/static', name: 'Static directory' }, ]; @@ -41,26 +40,6 @@ for (const check of checks) { } } -// Test the copy command -console.log('\nšŸ“‹ Testing copy command...'); -try { - execSync('cp -r .next/static .next/standalone/.next/', { stdio: 'inherit' }); - console.log('āœ… Copy command successful'); -} catch (e) { - console.error('āŒ Copy command failed'); - allPassed = false; -} - -// Check final structure -console.log('\nšŸ“ Final structure check...'); -const finalPath = '.next/standalone/.next/static'; -if (fs.existsSync(finalPath)) { - console.log('āœ… Static files copied successfully'); -} else { - console.error('āŒ Static files not in final location'); - allPassed = false; -} - if (!allPassed) { console.error('\nāŒ Build test failed! Do not push.'); process.exit(1); diff --git a/terraform/main.tf b/terraform/main.tf index 6256870..9a07461 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -15,7 +15,7 @@ provider "aws" { resource "aws_amplify_app" "filamenteka" { name = "filamenteka" repository = var.github_repository - platform = "WEB_COMPUTE" + platform = "WEB" # GitHub access token for private repos access_token = var.github_token