chore(quality): type-check and lint gates in pre-deploy, clean lint/tsc
CI Pipeline with Test Management / 🧪 Run Tests & Generate Reports (push) Waiting to run
CI Pipeline with Test Management / 🐳 Docker Integration Tests (push) Blocked by required conditions
CI Pipeline with Test Management / 🏗️ Build Docker Image (push) Blocked by required conditions
CI Pipeline with Test Management / 📊 Generate Test Summary (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🧪 Run Tests & Generate Reports (push) Waiting to run
Test Reporting & Gherkin Analysis / 📊 Analyze Test Coverage (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🔄 Sync with Linear (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / ⚡ Performance Monitoring (push) Blocked by required conditions

- pre-deploy suite now runs tsc --noEmit and eslint; any failure aborts
  the release
- fix all TypeScript errors (FooterConfig.copyright removed after the CMS
  move; test guards/casts)
- fix all ESLint errors: <a>→<Link> and <img>→<Image> in Header/Footer,
  remove unused imports and explicit any in src
- eslint config relaxes no-explicit-any/no-require-imports/no-unused-vars
  for test and CommonJS config files (legitimate usage)

Closes MITHOME-81
This commit is contained in:
Do Siki
2026-08-22 12:37:22 +02:00
parent 162e5782e9
commit d908f6b1b4
9 changed files with 41 additions and 14 deletions
+19
View File
@@ -20,6 +20,25 @@ const eslintConfig = [
"next-env.d.ts", "next-env.d.ts",
], ],
}, },
{
// WHY: test suites legitimately use `any` mocks, jest globals and CommonJS
// require(); jest/playwright config files are CommonJS by design. Relax the
// strict rules there so lint failures point at real production-code issues.
files: [
"**/*.test.ts",
"**/*.test.tsx",
"jest.config*.js",
"jest.setup*.js",
"jest.globalSetup*.js",
"playwright.config.ts",
],
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-require-imports": "off",
"@typescript-eslint/no-unused-vars": "off",
"react/display-name": "off",
},
},
]; ];
export default eslintConfig; export default eslintConfig;
+2 -1
View File
@@ -91,7 +91,8 @@ describe('Docker Environment Integration Tests', () => {
const mozditDb = mongoClient.db('mozdit') const mozditDb = mongoClient.db('mozdit')
const siteConfig = await mozditDb.collection('site_config').findOne() const siteConfig = await mozditDb.collection('site_config').findOne()
if (!siteConfig) throw new Error('site_config document not found')
expect(siteConfig).toBeTruthy() expect(siteConfig).toBeTruthy()
expect(siteConfig).toHaveProperty('type', 'site_config') expect(siteConfig).toHaveProperty('type', 'site_config')
expect(siteConfig).toHaveProperty('environment', 'development') expect(siteConfig).toHaveProperty('environment', 'development')
+1 -2
View File
@@ -1,4 +1,3 @@
import { siteConfig } from '@/config/site'
import { content } from '@/content' import { content } from '@/content'
const { home: pageContent } = content.pages const { home: pageContent } = content.pages
@@ -94,7 +93,7 @@ export default function Home() {
</h2> </h2>
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 stagger-children"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 stagger-children">
{pageContent.about.usps.map((usp: any, index: number) => ( {pageContent.about.usps.map((usp, index) => (
<div <div
key={usp.id} key={usp.id}
className="group text-center p-6 rounded-xl transition-all duration-300 hover-lift animate-fade-in-up" className="group text-center p-6 rounded-xl transition-all duration-300 hover-lift animate-fade-in-up"
+4 -3
View File
@@ -2,6 +2,7 @@
import { siteConfig } from '@/config/site' import { siteConfig } from '@/config/site'
import { content } from '@/content' import { content } from '@/content'
import Link from 'next/link'
export default function Footer() { export default function Footer() {
return ( return (
@@ -16,7 +17,7 @@ export default function Footer() {
<div className="grid grid-cols-1 md:grid-cols-4 gap-8 lg:gap-12"> <div className="grid grid-cols-1 md:grid-cols-4 gap-8 lg:gap-12">
{/* Company Info */} {/* Company Info */}
<div className="md:col-span-2"> <div className="md:col-span-2">
<a <Link
href="/" href="/"
className="inline-flex items-center gap-2 text-xl font-bold mb-4 transition-colors duration-200" className="inline-flex items-center gap-2 text-xl font-bold mb-4 transition-colors duration-200"
style={{ color: 'var(--color-primary-600)' }} style={{ color: 'var(--color-primary-600)' }}
@@ -26,7 +27,7 @@ export default function Footer() {
className="inline-block w-2 h-2 rounded-full animate-pulse-slow" className="inline-block w-2 h-2 rounded-full animate-pulse-slow"
style={{ background: 'var(--color-success-500)' }} style={{ background: 'var(--color-success-500)' }}
/> />
</a> </Link>
<p <p
className="mb-6 max-w-md leading-relaxed" className="mb-6 max-w-md leading-relaxed"
style={{ color: 'var(--color-foreground-muted)' }} style={{ color: 'var(--color-foreground-muted)' }}
@@ -104,7 +105,7 @@ export default function Footer() {
Szolgáltatások Szolgáltatások
</h3> </h3>
<ul className="space-y-3"> <ul className="space-y-3">
{content.pages.home.services.items.map((service: any) => ( {content.pages.home.services.items.map((service) => (
<li <li
key={service.id} key={service.id}
className="flex items-center gap-2 text-sm" className="flex items-center gap-2 text-sm"
+8 -4
View File
@@ -4,6 +4,8 @@ import { siteConfig } from '@/config/site'
import { common } from '@/content' import { common } from '@/content'
import { useState, useEffect } from 'react' import { useState, useEffect } from 'react'
import { ThemeToggle } from './ThemeProvider' import { ThemeToggle } from './ThemeProvider'
import Link from 'next/link'
import Image from 'next/image'
export default function Header() { export default function Header() {
const [isMenuOpen, setIsMenuOpen] = useState(false) const [isMenuOpen, setIsMenuOpen] = useState(false)
@@ -46,21 +48,23 @@ export default function Header() {
<div className="flex justify-between items-center h-16"> <div className="flex justify-between items-center h-16">
{/* Logo */} {/* Logo */}
<div className="flex-shrink-0"> <div className="flex-shrink-0">
<a <Link
href="/" href="/"
className="group flex items-center gap-2 transition-all duration-200" className="group flex items-center gap-2 transition-all duration-200"
> >
<img <Image
src="/mozdit_logo_text.png" src="/mozdit_logo_text.png"
alt={siteConfig.general.name} alt={siteConfig.general.name}
width={500}
height={115}
className="h-10 w-auto transition-transform duration-200 group-hover:scale-105" className="h-10 w-auto transition-transform duration-200 group-hover:scale-105"
/> />
</a> </Link>
</div> </div>
{/* Desktop Navigation */} {/* Desktop Navigation */}
<div className="hidden md:flex items-center space-x-1"> <div className="hidden md:flex items-center space-x-1">
{siteConfig.navigation.main.map((item, index) => ( {siteConfig.navigation.main.map((item) => (
<a <a
key={item.href} key={item.href}
href={item.href} href={item.href}
+3 -2
View File
@@ -23,7 +23,8 @@ describe('Logger', () => {
it('should create logger with correct configuration', () => { it('should create logger with correct configuration', () => {
// Set NODE_ENV to development to get debug level // Set NODE_ENV to development to get debug level
process.env.NODE_ENV = 'development' // NODE_ENV is typed read-only in @types/node — assign via a wider type.
;(process.env as unknown as Record<string, string>).NODE_ENV = 'development'
// Import after clearing modules // Import after clearing modules
require('./logger') require('./logger')
@@ -54,7 +55,7 @@ describe('Logger', () => {
// Clear the mock calls to avoid interference from logger creation // Clear the mock calls to avoid interference from logger creation
const mockLogger = mockedWinston.createLogger() const mockLogger = mockedWinston.createLogger()
mockLogger.child.mockClear() ;(mockLogger.child as jest.Mock).mockClear()
const componentLogger = createComponentLogger('test-component') const componentLogger = createComponentLogger('test-component')
expect(logger.child).toHaveBeenCalledWith({ component: 'test-component' }) expect(logger.child).toHaveBeenCalledWith({ component: 'test-component' })
+1 -1
View File
@@ -92,7 +92,7 @@ export const generateRequestId = (): string =>
export const withTiming = async <T>( export const withTiming = async <T>(
operation: string, operation: string,
fn: () => Promise<T>, fn: () => Promise<T>,
metadata: any = {} metadata: Record<string, unknown> = {}
): Promise<T> => { ): Promise<T> => {
const startTime = Date.now() const startTime = Date.now()
logger.debug(`Started ${operation}`, metadata) logger.debug(`Started ${operation}`, metadata)
+1 -1
View File
@@ -74,7 +74,7 @@ export interface AboutSectionConfig {
} }
export interface FooterConfig { export interface FooterConfig {
copyright: string // copyright text lives in content/common.json (footer.copyright) — CMS-editable
links: { links: {
label: string label: string
href: string href: string
+2
View File
@@ -24,6 +24,8 @@ run() {
# ── Weboldal (proto) ───────────────────────────────────────────────────────── # ── Weboldal (proto) ─────────────────────────────────────────────────────────
run "proto: unit tesztek (jest, 60+)" bash -c "cd '${ROOT}/proto' && npm test --silent" run "proto: unit tesztek (jest, 60+)" bash -c "cd '${ROOT}/proto' && npm test --silent"
run "proto: típusellenőrzés (tsc --noEmit)" bash -c "cd '${ROOT}/proto' && npx tsc --noEmit"
run "proto: lint (eslint)" bash -c "cd '${ROOT}/proto' && npm run lint"
# ── Tartalom ───────────────────────────────────────────────────────────────── # ── Tartalom ─────────────────────────────────────────────────────────────────
run "content: séma-validáció (minden JSON)" node "${ROOT}/scripts/test-content-schema.js" run "content: séma-validáció (minden JSON)" node "${ROOT}/scripts/test-content-schema.js"