Barazo default frontend barazo.forum
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(review): Address PR review feedback for M1-M3

- Add CI/CD GitHub Actions workflow (ci.yml)

- Add Docker build workflow (docker.yml)

- Add multi-stage Dockerfile for production

- Fix dark mode color mapping to use slate-dark-* variants

- Enable system theme preference (enableSystem: true)

- Remove lucide-react dependency (using Phosphor Icons only)

- Add .nvmrc with Node 24.11.0

- Remove hardcoded path from next.config.ts

- Add shadcn/ui components.json configuration

- Add health check API route (/api/health)

Refs: specs/prd-web.md Section 9 (M1-M3)

+326 -22
+156
.github/workflows/ci.yml
··· 1 + name: CI 2 + 3 + on: 4 + push: 5 + branches: [main, develop] 6 + pull_request: 7 + branches: [main, develop] 8 + 9 + concurrency: 10 + group: ${{ github.workflow }}-${{ github.ref }} 11 + cancel-in-progress: true 12 + 13 + jobs: 14 + lint: 15 + name: Lint 16 + runs-on: ubuntu-latest 17 + steps: 18 + - name: Checkout 19 + uses: actions/checkout@v4 20 + 21 + - name: Setup Node.js 22 + uses: actions/setup-node@v4 23 + with: 24 + node-version: '24' 25 + cache: 'pnpm' 26 + 27 + - name: Install pnpm 28 + uses: pnpm/action-setup@v2 29 + with: 30 + version: 9 31 + 32 + - name: Install dependencies 33 + run: pnpm install --frozen-lockfile 34 + 35 + - name: Run ESLint 36 + run: pnpm lint 37 + 38 + - name: Check formatting 39 + run: pnpm format:check 40 + 41 + typecheck: 42 + name: Type Check 43 + runs-on: ubuntu-latest 44 + steps: 45 + - name: Checkout 46 + uses: actions/checkout@v4 47 + 48 + - name: Setup Node.js 49 + uses: actions/setup-node@v4 50 + with: 51 + node-version: '24' 52 + cache: 'pnpm' 53 + 54 + - name: Install pnpm 55 + uses: pnpm/action-setup@v2 56 + with: 57 + version: 9 58 + 59 + - name: Install dependencies 60 + run: pnpm install --frozen-lockfile 61 + 62 + - name: Run TypeScript 63 + run: pnpm typecheck 64 + 65 + test: 66 + name: Test 67 + runs-on: ubuntu-latest 68 + steps: 69 + - name: Checkout 70 + uses: actions/checkout@v4 71 + 72 + - name: Setup Node.js 73 + uses: actions/setup-node@v4 74 + with: 75 + node-version: '24' 76 + cache: 'pnpm' 77 + 78 + - name: Install pnpm 79 + uses: pnpm/action-setup@v2 80 + with: 81 + version: 9 82 + 83 + - name: Install dependencies 84 + run: pnpm install --frozen-lockfile 85 + 86 + - name: Run tests 87 + run: pnpm test 88 + 89 + build: 90 + name: Build 91 + runs-on: ubuntu-latest 92 + needs: [lint, typecheck, test] 93 + steps: 94 + - name: Checkout 95 + uses: actions/checkout@v4 96 + 97 + - name: Setup Node.js 98 + uses: actions/setup-node@v4 99 + with: 100 + node-version: '24' 101 + cache: 'pnpm' 102 + 103 + - name: Install pnpm 104 + uses: pnpm/action-setup@v2 105 + with: 106 + version: 9 107 + 108 + - name: Install dependencies 109 + run: pnpm install --frozen-lockfile 110 + 111 + - name: Build application 112 + run: pnpm build 113 + 114 + - name: Upload build artifacts 115 + uses: actions/upload-artifact@v4 116 + with: 117 + name: build 118 + path: dist/ 119 + retention-days: 7 120 + 121 + accessibility: 122 + name: Accessibility Audit 123 + runs-on: ubuntu-latest 124 + needs: build 125 + steps: 126 + - name: Checkout 127 + uses: actions/checkout@v4 128 + 129 + - name: Setup Node.js 130 + uses: actions/setup-node@v4 131 + with: 132 + node-version: '24' 133 + cache: 'pnpm' 134 + 135 + - name: Install pnpm 136 + uses: pnpm/action-setup@v2 137 + with: 138 + version: 9 139 + 140 + - name: Install dependencies 141 + run: pnpm install --frozen-lockfile 142 + 143 + - name: Build application 144 + run: pnpm build 145 + 146 + - name: Install axe-core CLI 147 + run: pnpm add -g @axe-core/cli 148 + 149 + - name: Serve build 150 + run: npx serve dist -l 3000 & 151 + 152 + - name: Wait for server 153 + run: sleep 5 154 + 155 + - name: Run axe accessibility check 156 + run: axe http://localhost:3000 --exit
+66
.github/workflows/docker.yml
··· 1 + name: Docker 2 + 3 + on: 4 + push: 5 + tags: 6 + - 'v*' 7 + workflow_dispatch: 8 + 9 + env: 10 + REGISTRY: ghcr.io 11 + IMAGE_NAME: ${{ github.repository }} 12 + 13 + jobs: 14 + build-and-push: 15 + name: Build and Push Docker Image 16 + runs-on: ubuntu-latest 17 + permissions: 18 + contents: read 19 + packages: write 20 + attestations: write 21 + id-token: write 22 + 23 + steps: 24 + - name: Checkout 25 + uses: actions/checkout@v4 26 + 27 + - name: Set up Docker Buildx 28 + uses: docker/setup-buildx-action@v3 29 + 30 + - name: Login to Container Registry 31 + uses: docker/login-action@v3 32 + with: 33 + registry: ${{ env.REGISTRY }} 34 + username: ${{ github.actor }} 35 + password: ${{ secrets.GITHUB_TOKEN }} 36 + 37 + - name: Extract metadata 38 + id: meta 39 + uses: docker/metadata-action@v5 40 + with: 41 + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 42 + tags: | 43 + type=ref,event=branch 44 + type=ref,event=pr 45 + type=semver,pattern={{version}} 46 + type=semver,pattern={{major}}.{{minor}} 47 + type=semver,pattern={{major}} 48 + type=sha 49 + 50 + - name: Build and push Docker image 51 + uses: docker/build-push-action@v5 52 + with: 53 + context: . 54 + push: true 55 + tags: ${{ steps.meta.outputs.tags }} 56 + labels: ${{ steps.meta.outputs.labels }} 57 + cache-from: type=gha 58 + cache-to: type=gha,mode=max 59 + platforms: linux/amd64,linux/arm64 60 + 61 + - name: Generate artifact attestation 62 + uses: actions/attest-build-provenance@v1 63 + with: 64 + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 65 + subject-digest: ${{ steps.build.outputs.digest }} 66 + push-to-registry: true
+1
.nvmrc
··· 1 + 24.11.0
+55
Dockerfile
··· 1 + # Multi-stage build for production 2 + # Stage 1: Dependencies 3 + FROM node:24-alpine AS deps 4 + RUN apk add --no-cache libc6-compat 5 + WORKDIR /app 6 + 7 + # Install pnpm 8 + RUN corepack enable && corepack prepare pnpm@9.0.0 --activate 9 + 10 + # Copy package files 11 + COPY package.json pnpm-lock.yaml ./ 12 + RUN pnpm install --frozen-lockfile 13 + 14 + # Stage 2: Builder 15 + FROM node:24-alpine AS builder 16 + WORKDIR /app 17 + 18 + # Install pnpm 19 + RUN corepack enable && corepack prepare pnpm@9.0.0 --activate 20 + 21 + # Copy dependencies from deps stage 22 + COPY --from=deps /app/node_modules ./node_modules 23 + COPY . . 24 + 25 + # Build application 26 + ENV NEXT_TELEMETRY_DISABLED=1 27 + RUN pnpm build 28 + 29 + # Stage 3: Production 30 + FROM node:24-alpine AS runner 31 + WORKDIR /app 32 + 33 + ENV NODE_ENV=production 34 + ENV NEXT_TELEMETRY_DISABLED=1 35 + 36 + # Create non-root user 37 + RUN addgroup --system --gid 1001 nodejs 38 + RUN adduser --system --uid 1001 nextjs 39 + 40 + # Copy static files from builder 41 + COPY --from=builder /app/dist ./dist 42 + COPY --from=builder /app/package.json ./package.json 43 + 44 + # Change ownership 45 + USER nextjs 46 + 47 + # Expose port 48 + EXPOSE 3000 49 + 50 + # Health check 51 + HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ 52 + CMD node -e "require('http').get('http://localhost:3000/api/health', (r) => r.statusCode === 200 ? process.exit(0) : process.exit(1))" 53 + 54 + # Start static server 55 + CMD ["npx", "serve", "dist", "-l", "3000"]
+17
components.json
··· 1 + { 2 + "$schema": "https://ui.shadcn.com/schema.json", 3 + "style": "default", 4 + "rsc": true, 5 + "tsx": true, 6 + "tailwind": { 7 + "config": "tailwind.config.ts", 8 + "css": "src/app/globals.css", 9 + "baseColor": "slate", 10 + "cssVariables": true, 11 + "prefix": "" 12 + }, 13 + "aliases": { 14 + "components": "@/components", 15 + "utils": "@/lib/utils" 16 + } 17 + }
-5
next.config.ts
··· 20 20 // Enable React Compiler (stable in Next.js 16) 21 21 reactCompiler: true, 22 22 23 - // Turbopack configuration 24 - turbopack: { 25 - root: '/Users/gxjansen/Documents/Git/barazo-forum/barazo-web', 26 - }, 27 - 28 23 // Environment variables available at build time 29 24 env: { 30 25 NEXT_PUBLIC_APP_VERSION: process.env.npm_package_version || '0.1.0',
-1
package.json
··· 57 57 "class-variance-authority": "^0.7.1", 58 58 "clsx": "^2.1.1", 59 59 "isomorphic-dompurify": "^2.20.0", 60 - "lucide-react": "^0.468.0", 61 60 "next": "16.1.6", 62 61 "next-themes": "^0.4.4", 63 62 "react": "19.2.3",
+14
src/app/api/health/route.ts
··· 1 + /** 2 + * Health Check API Route 3 + * Returns 200 OK for Docker health checks and monitoring 4 + */ 5 + export const dynamic = 'force-static' 6 + 7 + export async function GET() { 8 + return new Response(JSON.stringify({ status: 'ok', timestamp: new Date().toISOString() }), { 9 + status: 200, 10 + headers: { 11 + 'Content-Type': 'application/json', 12 + }, 13 + }) 14 + }
+16 -15
src/app/globals.css
··· 202 202 } 203 203 204 204 .dark { 205 - --color-background: var(--slate-1); 206 - --color-foreground: var(--slate-12); 207 - --color-muted: var(--slate-11); 208 - --color-muted-foreground: var(--slate-9); 209 - --color-border: var(--slate-6); 210 - --color-border-hover: var(--slate-7); 211 - --color-input: var(--slate-3); 212 - --color-input-focus: var(--slate-4); 213 - --color-ring: var(--cyan-8); 214 - --color-ring-offset: var(--slate-1); 205 + /* Dark mode uses Radix dark color scales */ 206 + --color-background: var(--slate-dark-1); 207 + --color-foreground: var(--slate-dark-12); 208 + --color-muted: var(--slate-dark-11); 209 + --color-muted-foreground: var(--slate-dark-9); 210 + --color-border: var(--slate-dark-6); 211 + --color-border-hover: var(--slate-dark-7); 212 + --color-input: var(--slate-dark-3); 213 + --color-input-focus: var(--slate-dark-4); 214 + --color-ring: var(--cyan-dark-8); 215 + --color-ring-offset: var(--slate-dark-1); 215 216 216 - --color-card: var(--slate-2); 217 - --color-card-foreground: var(--slate-12); 218 - --color-card-hover: var(--slate-3); 219 - --color-popover: var(--slate-1); 220 - --color-popover-foreground: var(--slate-12); 217 + --color-card: var(--slate-dark-2); 218 + --color-card-foreground: var(--slate-dark-12); 219 + --color-card-hover: var(--slate-dark-3); 220 + --color-popover: var(--slate-dark-1); 221 + --color-popover-foreground: var(--slate-dark-12); 221 222 } 222 223 223 224 /* Base styles */
+1 -1
src/app/layout.tsx
··· 58 58 <ThemeProvider 59 59 attribute="class" 60 60 defaultTheme="dark" 61 - enableSystem={false} 61 + enableSystem={true} 62 62 disableTransitionOnChange 63 63 > 64 64 {children}