Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aec56dfc23 | ||
| a12a0e5207 | |||
| e337bd67b1 |
18
.devcontainer/devcontainer.json
Normal file
18
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "Flyer Crawler Dev (Ubuntu 22.04)",
|
||||||
|
"dockerComposeFile": ["../compose.dev.yml"],
|
||||||
|
"service": "app",
|
||||||
|
"workspaceFolder": "/app",
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"remoteUser": "root",
|
||||||
|
// Automatically install dependencies when the container is created.
|
||||||
|
// This runs inside the container, populating the isolated node_modules volume.
|
||||||
|
"postCreateCommand": "npm install",
|
||||||
|
"postAttachCommand": "npm run dev:container",
|
||||||
|
// Try to start podman machine, but exit with success (0) even if it's already running
|
||||||
|
"initializeCommand": "powershell -Command \"podman machine start; exit 0\""
|
||||||
|
}
|
||||||
31
Dockerfile.dev
Normal file
31
Dockerfile.dev
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Use Ubuntu 22.04 (LTS) as the base image to match production
|
||||||
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
# Set environment variables to non-interactive to avoid prompts during installation
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
# Update package lists and install essential tools
|
||||||
|
# - curl: for downloading Node.js setup script
|
||||||
|
# - git: for version control operations
|
||||||
|
# - build-essential: for compiling native Node.js modules (node-gyp)
|
||||||
|
# - python3: required by some Node.js build tools
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
build-essential \
|
||||||
|
python3 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install Node.js 20.x (LTS) from NodeSource
|
||||||
|
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||||
|
&& apt-get install -y nodejs
|
||||||
|
|
||||||
|
# Set the working directory inside the container
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Set default environment variables for development
|
||||||
|
ENV NODE_ENV=development
|
||||||
|
ENV NODE_OPTIONS='--max-old-space-size=8192'
|
||||||
|
|
||||||
|
# Default command keeps the container running so you can attach to it
|
||||||
|
CMD ["bash"]
|
||||||
52
compose.dev.yml
Normal file
52
compose.dev.yml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
container_name: flyer-crawler-dev
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.dev
|
||||||
|
volumes:
|
||||||
|
# Mount the current directory to /app in the container
|
||||||
|
- .:/app
|
||||||
|
# Create a volume for node_modules to avoid conflicts with Windows host
|
||||||
|
# and improve performance.
|
||||||
|
- node_modules_data:/app/node_modules
|
||||||
|
ports:
|
||||||
|
- '3000:3000' # Frontend (Vite default)
|
||||||
|
- '3001:3001' # Backend API
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=development
|
||||||
|
- DB_HOST=postgres
|
||||||
|
- DB_USER=postgres
|
||||||
|
- DB_PASSWORD=postgres
|
||||||
|
- DB_NAME=flyer_crawler_dev
|
||||||
|
- REDIS_URL=redis://redis:6379
|
||||||
|
# Add other secrets here or use a .env file
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
- redis
|
||||||
|
# Keep container running so VS Code can attach
|
||||||
|
command: tail -f /dev/null
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
image: docker.io/library/postgis/postgis:15-3.4
|
||||||
|
container_name: flyer-crawler-postgres
|
||||||
|
ports:
|
||||||
|
- '5432:5432'
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: postgres
|
||||||
|
POSTGRES_PASSWORD: postgres
|
||||||
|
POSTGRES_DB: flyer_crawler_dev
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: docker.io/library/redis:alpine
|
||||||
|
container_name: flyer-crawler-redis
|
||||||
|
ports:
|
||||||
|
- '6379:6379'
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
|
node_modules_data:
|
||||||
4281
package-lock.json
generated
4281
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@@ -1,17 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "flyer-crawler",
|
"name": "flyer-crawler",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.14",
|
"version": "0.0.15",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "concurrently \"npm:start:dev\" \"vite\"",
|
"dev": "concurrently \"npm:start:dev\" \"vite\"",
|
||||||
|
"dev:container": "concurrently \"npm:start:dev\" \"vite --host\"",
|
||||||
"start": "npm run start:prod",
|
"start": "npm run start:prod",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"test": "NODE_ENV=test tsx ./node_modules/vitest/vitest.mjs run",
|
"test": "cross-env NODE_ENV=test tsx ./node_modules/vitest/vitest.mjs run",
|
||||||
|
"test-wsl": "cross-env NODE_ENV=test vitest run",
|
||||||
"test:coverage": "npm run clean && npm run test:unit -- --coverage && npm run test:integration -- --coverage",
|
"test:coverage": "npm run clean && npm run test:unit -- --coverage && npm run test:integration -- --coverage",
|
||||||
"test:unit": "NODE_ENV=test tsx ./node_modules/vitest/vitest.mjs run --project unit -c vite.config.ts",
|
"test:unit": "NODE_ENV=test tsx --max-old-space-size=8192 ./node_modules/vitest/vitest.mjs run --project unit -c vite.config.ts",
|
||||||
"test:integration": "NODE_ENV=test tsx ./node_modules/vitest/vitest.mjs run --project integration -c vitest.config.integration.ts",
|
"test:integration": "NODE_ENV=test tsx --max-old-space-size=8192 ./node_modules/vitest/vitest.mjs run --project integration -c vitest.config.integration.ts",
|
||||||
"format": "prettier --write .",
|
"format": "prettier --write .",
|
||||||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||||
"type-check": "tsc --noEmit",
|
"type-check": "tsc --noEmit",
|
||||||
@@ -20,6 +22,7 @@
|
|||||||
"start:dev": "NODE_ENV=development tsx watch server.ts",
|
"start:dev": "NODE_ENV=development tsx watch server.ts",
|
||||||
"start:prod": "NODE_ENV=production tsx server.ts",
|
"start:prod": "NODE_ENV=production tsx server.ts",
|
||||||
"start:test": "NODE_ENV=test NODE_V8_COVERAGE=.coverage/tmp/integration-server tsx server.ts",
|
"start:test": "NODE_ENV=test NODE_V8_COVERAGE=.coverage/tmp/integration-server tsx server.ts",
|
||||||
|
"db:reset:dev": "NODE_ENV=development tsx src/db/seed.ts",
|
||||||
"db:reset:test": "NODE_ENV=test tsx src/db/seed.ts",
|
"db:reset:test": "NODE_ENV=test tsx src/db/seed.ts",
|
||||||
"worker:prod": "NODE_ENV=production tsx src/services/queueService.server.ts"
|
"worker:prod": "NODE_ENV=production tsx src/services/queueService.server.ts"
|
||||||
},
|
},
|
||||||
@@ -95,6 +98,7 @@
|
|||||||
"autoprefixer": "^10.4.22",
|
"autoprefixer": "^10.4.22",
|
||||||
"c8": "^10.1.3",
|
"c8": "^10.1.3",
|
||||||
"concurrently": "^9.2.1",
|
"concurrently": "^9.2.1",
|
||||||
|
"cross-env": "^10.1.0",
|
||||||
"eslint": "9.39.1",
|
"eslint": "9.39.1",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-plugin-react": "7.37.5",
|
"eslint-plugin-react": "7.37.5",
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ CREATE TABLE IF NOT EXISTS public.stores (
|
|||||||
created_at TIMESTAMPTZ DEFAULT now() NOT NULL,
|
created_at TIMESTAMPTZ DEFAULT now() NOT NULL,
|
||||||
updated_at TIMESTAMPTZ DEFAULT now() NOT NULL,
|
updated_at TIMESTAMPTZ DEFAULT now() NOT NULL,
|
||||||
created_by UUID REFERENCES public.users(user_id) ON DELETE SET NULL
|
created_by UUID REFERENCES public.users(user_id) ON DELETE SET NULL
|
||||||
|
);
|
||||||
COMMENT ON TABLE public.stores IS 'Stores metadata for grocery store chains (e.g., Safeway, Kroger).';
|
COMMENT ON TABLE public.stores IS 'Stores metadata for grocery store chains (e.g., Safeway, Kroger).';
|
||||||
|
|
||||||
-- 5. The 'categories' table for normalized category data.
|
-- 5. The 'categories' table for normalized category data.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/// <reference types="vitest" />
|
/// <reference types="vitest" />
|
||||||
|
// vitest.config.ts
|
||||||
import { defineConfig } from 'vitest/config';
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@@ -6,12 +7,11 @@ export default defineConfig({
|
|||||||
globals: true,
|
globals: true,
|
||||||
environment: 'jsdom',
|
environment: 'jsdom',
|
||||||
// This setup file is where we can add global test configurations
|
// This setup file is where we can add global test configurations
|
||||||
setupFiles: [
|
setupFiles: ['./src/tests/setup/tests-setup-unit.ts'],
|
||||||
'./src/tests/setup/tests-setup-unit.ts',
|
// , './src/tests/setup/mockHooks.ts'
|
||||||
'./src/tests/setup/mockHooks.ts',
|
// removed this from above: './src/tests/setup/mockComponents.tsx'
|
||||||
'./src/tests/setup/mockComponents.tsx'
|
|
||||||
],
|
|
||||||
// This line is the key fix: it tells Vitest to include the type definitions
|
// This line is the key fix: it tells Vitest to include the type definitions
|
||||||
include: ['src/**/*.test.tsx'],
|
include: ['src/**/*.test.{ts,tsx}'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user