Files
TehRiehlDeal 8c10124272
CI / test (push) Successful in 25s
CI / lint (push) Successful in 28s
CI / secrets-scan (push) Successful in 5s
CI / vuln-scan (push) Successful in 12s
CI / sast (push) Successful in 10s
CI / build-images (push) Failing after 51s
CI / image-scan (push) Has been skipped
CI / push (push) Has been skipped
Build, scan, and push images to Harbor on every main push
Wires up the CD half of the pipeline. New jobs build multi-stage Docker
images for the frontend and backend, run a Trivy image scan that fails
on HIGH/CRITICAL findings, and push to harbor.tehriehldeal.com on main
only. Each push tags <version> (from package.json), <sha>, and latest;
a pre-push existence check refuses to overwrite a version tag that
already points at a different digest, forcing a real bump.

The Vite frontend now reads runtime config from window.__RUNTIME_CONFIG__,
populated by /config.js which nginx renders from container env vars at
startup via envsubst. A getConfig() helper falls back to import.meta.env
for `pnpm dev` and Vitest, so existing test scaffolding keeps working.
PWA workbox excludes /config.js from precache and serves it NetworkOnly
to keep stale config from surviving a container restart.

Bumps frontend 0.0.0→0.1.0 and backend 0.0.1→0.1.0 (production
deployment is a meaningful new capability for both packages).

Also fixes four pre-existing tsc -b errors that the new vite build step
in the frontend Dockerfile would otherwise hit: global.fetch →
globalThis.fetch in three test files, null-guard in Activity.tsx
account filter, type cast on Recharts Pie onClick in Dashboard.tsx,
typed callback signature on the auth.test.ts onAuthStateChange mock.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 15:49:01 -07:00

55 lines
1.9 KiB
JavaScript

import js from '@eslint/js';
import globals from 'globals';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
import tseslint from 'typescript-eslint';
import { defineConfig, globalIgnores } from 'eslint/config';
export default defineConfig([
globalIgnores(['dist', 'coverage']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
rules: {
// react-hooks v6 added this rule in late 2025; several legitimate
// patterns in this codebase (route-change drawer close, prop→state
// sync in PWAUpdatePrompt) trip it. Track these as warnings until
// we can refactor each one with proper visual testing.
'react-hooks/set-state-in-effect': 'warn',
// Allow underscore-prefixed args/vars as the standard signal for
// intentionally-unused parameters (e.g. typed callback signatures
// on mocks where the body doesn't reference the arg).
'@typescript-eslint/no-unused-vars': [
'error',
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
],
},
},
{
// Tests routinely use `any` for mock/stub typing. Allow it in test
// files only, not production code.
files: ['**/*.test.{ts,tsx}', '**/__tests__/**/*.{ts,tsx}'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
},
},
{
// shadcn/ui generators co-locate the cva variant config alongside the
// component, which the react-refresh rule flags as breaking Fast Refresh
// for non-component exports. The pattern is intentional; demote here.
files: ['src/components/ui/**/*.{ts,tsx}'],
rules: {
'react-refresh/only-export-components': 'warn',
},
},
]);