Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 13 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Docker ignore file
node_modules
npm-debug.log
.env
.env.local
dist
coverage
.git
.gitignore
README.md
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The .dockerignore file excludes README.md on line 10 and then uses a broader pattern *.md on line 13, which also excludes README.md. The first specific exclusion is redundant. While not harmful, it's cleaner to remove line 10 since line 13 already covers it.

Suggested change
README.md

Copilot uses AI. Check for mistakes.
.vscode
.idea
*.md
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PORT=3000
22 changes: 22 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"env": {
"es2022": true,
"node": true,
"browser": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"rules": {
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"@typescript-eslint/explicit-function-return-type": "off"
},
"ignorePatterns": ["dist", "node_modules", "*.config.js"]
}
48 changes: 48 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]

jobs:
build-and-test:
runs-on: ubuntu-latest

permissions:
contents: read

strategy:
matrix:
node-version: [18.x, 20.x]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Lint code
run: npm run lint

- name: Build backend
run: npm run build

- name: Run tests
run: npm test

- name: Upload coverage reports
if: matrix.node-version == '20.x'
uses: codecov/codecov-action@v3
with:
file: ./coverage/coverage-final.json
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the CI workflow, the coverage upload step references ./coverage/coverage-final.json but Vitest with the v8 provider generates coverage in different file formats. The standard output is typically in subdirectories like ./coverage/lcov.info or the JSON files might have different names. This could cause the coverage upload to fail silently. Consider using a glob pattern or verifying the actual output path from Vitest's v8 coverage provider.

Suggested change
file: ./coverage/coverage-final.json
file: ./coverage/*.json,./coverage/lcov.info

Copilot uses AI. Check for mistakes.
flags: unittests
fail_ci_if_error: false
34 changes: 34 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Dependencies
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Build output
dist/
build/
*.tsbuildinfo

# Environment
.env
.env.local
.env.*.local

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Testing
coverage/
.nyc_output/

# Logs
logs/
*.log
9 changes: 9 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"arrowParens": "always"
}
62 changes: 62 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Build stage for backend
FROM node:20-alpine AS backend-builder

WORKDIR /app

# Copy package files
COPY package*.json ./
COPY tsconfig.json ./

# Install dependencies
RUN npm ci

# Copy source files
COPY src ./src

# Build backend
RUN npm run build
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Dockerfile runs npm run build on line 17, but at that point only the backend source files have been copied (line 14). The frontend source files are not available yet, so npm run build which includes npm run frontend:build will fail. The backend and frontend builders should be independent, with the backend builder only running tsc to compile TypeScript.

Suggested change
RUN npm run build
RUN npx tsc

Copilot uses AI. Check for mistakes.

# Build stage for frontend
FROM node:20-alpine AS frontend-builder

WORKDIR /app

# Copy package files
COPY package*.json ./
COPY vite.config.ts ./

# Install dependencies
RUN npm ci

# Copy frontend source
COPY frontend ./frontend

# Build frontend
RUN npm run frontend:build

# Production stage
FROM node:20-alpine

WORKDIR /app

# Copy package files and install production dependencies only
COPY package*.json ./
RUN npm ci --omit=dev

# Copy built backend from backend-builder
COPY --from=backend-builder /app/dist ./dist

# Copy built frontend from frontend-builder
COPY --from=frontend-builder /app/frontend/dist ./frontend/dist

# Create .env file with default values if not exists
RUN echo "PORT=3000" > .env.example

Comment on lines +52 to +54
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating a .env.example file inside the Docker image is misleading since this is runtime, not a template for users. The comment says "Create .env file with default values if not exists" but the command creates .env.example, not .env. If the intention is to provide default environment values, they should either be set as ENV variables directly or this line should be removed entirely since environment variables are already set via docker-compose.yml.

Suggested change
# Create .env file with default values if not exists
RUN echo "PORT=3000" > .env.example

Copilot uses AI. Check for mistakes.
# Expose port
EXPOSE 3000

# Set production environment
ENV NODE_ENV=production

# Start the server
CMD ["node", "dist/server.js"]
Loading
Loading