Skip to content

Commit 3ec055c

Browse files
Digidaiclaude
andcommitted
feat: 全面优化项目安全性、无障碍访问、SEO 和构建流程
## 安全性改进 - 移除 CSP 中的 unsafe-inline,改用 SCSS 样式 - 添加 Fuse.js CDN 的 SRI 完整性检查 - 更新 _headers 文件的安全策略 ## 无障碍访问 - 添加跳转链接 (Skip Link) 支持键盘导航 - 添加 focus-visible 键盘焦点样式 - 添加 .sr-only 屏幕阅读器专用类 ## 代码重构 - 将 CSS 重构为模块化 SCSS 架构 - 创建可复用的 product-card.html 组件 - 优化返回顶部按钮使用 CSS 类替代内联样式 ## SEO 和性能 - 增强 robots.txt 规则 - 添加静态资源缓存策略 - 添加大屏幕响应式断点 ## 数据验证增强 - URL 格式验证、描述长度检查、标签数量验证、未使用标签检测 ## 图片资源 - 创建 favicon.svg、logo.svg、og-image.svg - 添加 SVG 转 PNG 转换脚本 ## CI/CD 改进 - 添加 HTML 有效性检查 - 增强部署文件验证 ## 清理 - 删除 37 个未使用的标签页面 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 88fb68d commit 3ec055c

62 files changed

Lines changed: 2651 additions & 1888 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/jekyll-gh-pages.yml

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Sample workflow for building and deploying a Jekyll site to GitHub Pages
1+
# HireAI - Jekyll Site Build and Deploy
22
name: Deploy Jekyll with GitHub Pages dependencies preinstalled
33

44
on:
@@ -19,7 +19,6 @@ permissions:
1919
id-token: write
2020

2121
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
22-
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
2322
concurrency:
2423
group: "pages"
2524
cancel-in-progress: false
@@ -36,25 +35,43 @@ jobs:
3635
uses: ruby/setup-ruby@v1
3736
with:
3837
ruby-version: '3.2'
39-
bundler-cache: true # Caches gems
38+
bundler-cache: true
4039

4140
- name: Validate data consistency
4241
run: ruby _scripts/check_site_data.rb
4342

4443
- name: Build with Jekyll
4544
run: JEKYLL_ENV=production bundle exec jekyll build -d ./_site
4645

46+
- name: Check HTML validity
47+
uses: anishathalye/proof-html@v2
48+
with:
49+
directory: ./_site
50+
check_html: true
51+
check_opengraph: true
52+
check_img_http: true
53+
enforce_https: true
54+
check_favicon: true
55+
allow_hash_href: true
56+
ignore_urls: |
57+
https://fonts.googleapis.com
58+
https://fonts.gstatic.com
59+
https://cdn.jsdelivr.net
60+
continue-on-error: true
61+
4762
- name: Verify deployment files
4863
run: |
49-
if [ ! -f ./_site/.well-known/security.txt ]; then
50-
echo "::warning::Missing ./_site/.well-known/security.txt"
51-
fi
52-
if [ ! -f ./_site/_headers ]; then
53-
echo "::warning::Missing ./_site/_headers (only used by some hosts)"
54-
fi
55-
if [ ! -f ./_site/CNAME ]; then
56-
echo "::warning::Missing ./_site/CNAME"
57-
fi
64+
echo "Checking required files..."
65+
[ -f ./_site/index.html ] || echo "::error::Missing index.html"
66+
[ -f ./_site/sitemap.xml ] || echo "::warning::Missing sitemap.xml"
67+
[ -f ./_site/robots.txt ] || echo "::warning::Missing robots.txt"
68+
[ -f ./_site/.well-known/security.txt ] && echo "security.txt found" || echo "::warning::Missing security.txt"
69+
[ -f ./_site/_headers ] && echo "_headers found" || echo "::warning::Missing _headers"
70+
[ -f ./_site/CNAME ] && echo "CNAME found" || echo "::warning::Missing CNAME"
71+
72+
echo "Counting generated pages..."
73+
HTML_COUNT=$(find ./_site -name "*.html" | wc -l | tr -d ' ')
74+
echo "Generated $HTML_COUNT HTML pages"
5875
5976
- name: Setup Pages
6077
if: github.event_name != 'pull_request'

CONTRIBUTING.md

Lines changed: 269 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,276 @@
1-
# How to Contribute
1+
# Contributing to HireAI
22

3-
We welcome contributions to this project! If you have an HR AI product you'd like to add, please follow these steps.
3+
Thank you for your interest in contributing to HireAI! This document provides guidelines and instructions for contributing.
44

5-
## Adding a New Product Analysis
5+
## Table of Contents
66

7-
1. **Fork the repository:** Start by forking the project to your own GitHub account.
8-
2. **Create a new analysis file:** In the root directory, create a new markdown file for your analysis. The filename should be in the format `product-name-analysis.md`.
9-
3. **Use the template:** Copy the content of `_templates/analysis_template.md` into your new file. This will give you the correct structure for the analysis.
10-
4. **Fill out the analysis:** Complete the analysis to the best of your ability. Be objective and provide concrete examples where possible.
11-
5. **Update the data file:** Open the `_data/products.yml` file and add an entry for your new product. Make sure to include the `name`, `url`, `analysis` (linking to your new file), `description`, and `tags`.
12-
6. **Bake enrichment (recommended for `layout: analysis`):** Run `ruby _scripts/bake_analysis_enrichment.rb` to generate the Evaluation Guide, tag checklists, and related products block directly into Markdown.
13-
7. **Create a pull request:** Once you're happy with your analysis, create a pull request to merge your changes into the main repository.
7+
- [Getting Started](#getting-started)
8+
- [Development Setup](#development-setup)
9+
- [Project Structure](#project-structure)
10+
- [Adding a New Product](#adding-a-new-product)
11+
- [Writing Analysis Articles](#writing-analysis-articles)
12+
- [Creating Tag Pages](#creating-tag-pages)
13+
- [Code Style Guidelines](#code-style-guidelines)
14+
- [Submitting Changes](#submitting-changes)
1415

15-
## Contribution Guidelines
16+
## Getting Started
1617

17-
* **Be objective:** Provide a fair and balanced analysis of the product.
18-
* **Be thorough:** The more detailed your analysis, the more valuable it will be to others.
19-
* **Cite your sources:** If you're quoting statistics or making specific claims, please include a link to the source.
20-
* **Tags must have pages:** If you add a new tag, create the matching page under `tags/` (slug: lowercase, spaces → `-`).
18+
### Prerequisites
19+
20+
- Ruby 2.7 or higher
21+
- Bundler gem
22+
- Git
23+
24+
### Development Setup
25+
26+
1. **Clone the repository**
27+
```bash
28+
git clone https://github.com/Digidai/HireAI.git
29+
cd HireAI
30+
```
31+
32+
2. **Install dependencies**
33+
```bash
34+
bundle install
35+
```
36+
37+
3. **Run the development server**
38+
```bash
39+
bundle exec jekyll serve --livereload
40+
```
41+
42+
4. **Open in browser**
43+
```
44+
http://localhost:4000
45+
```
46+
47+
## Project Structure
48+
49+
```
50+
HireAI/
51+
├── _analyses/ # Product analysis articles (150+ files)
52+
├── _data/
53+
│ ├── products.yml # Main product database
54+
│ └── tag_checklists.yml # Tag evaluation checklists
55+
├── _includes/ # Reusable HTML components
56+
├── _layouts/ # Page layout templates
57+
├── _sass/ # SCSS modules
58+
│ ├── _variables.scss # CSS custom properties
59+
│ ├── _base.scss # Reset and base styles
60+
│ ├── _sidebar.scss # Navigation sidebar
61+
│ ├── _components.scss # Cards, buttons, tags
62+
│ ├── _layouts.scss # Page layouts
63+
│ ├── _product-detail.scss
64+
│ ├── _markdown.scss # Markdown content
65+
│ └── _responsive.scss # Media queries
66+
├── _scripts/ # Build and validation scripts
67+
├── assets/
68+
│ ├── css/main.scss # Main stylesheet entry
69+
│ ├── js/main.js # JavaScript functionality
70+
│ └── images/ # Static images
71+
├── tags/ # Tag pages (95+ files)
72+
└── *.md # Root-level pages
73+
```
74+
75+
## Adding a New Product
76+
77+
### Step 1: Add to Product Database
78+
79+
Edit `_data/products.yml` and add your product under the appropriate era category:
80+
81+
```yaml
82+
- era: "2020s - Intelligence Platforms"
83+
icon: "🧠"
84+
products:
85+
- name: "Your Product Name"
86+
url: "https://product-website.com"
87+
description: "Brief description (max 100 chars)"
88+
tags:
89+
- "ATS"
90+
- "AI"
91+
analysis: "_analyses/your-product-analysis.md"
92+
```
93+
94+
### Step 2: Create Analysis Article
95+
96+
Create a new file in `_analyses/`:
97+
98+
```markdown
99+
---
100+
layout: analysis
101+
title: "Your Product Name Analysis"
102+
description: "Deep-dive analysis of Your Product Name"
103+
permalink: /your-product-analysis/
104+
---
105+
106+
## Overview
107+
108+
Your analysis content here...
109+
```
110+
111+
### Step 3: Create Missing Tag Pages
112+
113+
If you introduced new tags, create corresponding pages in `tags/`:
114+
115+
```markdown
116+
---
117+
layout: tag_page
118+
tag: "Your New Tag"
119+
title: "Your New Tag"
120+
description: "Products with Your New Tag capability"
121+
permalink: /tags/your-new-tag/
122+
---
123+
124+
Optional introductory content about this tag.
125+
```
126+
127+
### Step 4: Validate Your Changes
128+
129+
Run the validation script:
130+
131+
```bash
132+
ruby _scripts/check_site_data.rb
133+
```
134+
135+
Expected output:
136+
```
137+
products=X
138+
analysis_pages=X
139+
tag_pages=X
140+
OK
141+
```
142+
143+
### Step 5: Bake Enrichment Content
144+
145+
Run the enrichment script to add related products and checklists:
146+
147+
```bash
148+
ruby _scripts/bake_analysis_enrichment.rb
149+
```
150+
151+
## Writing Analysis Articles
152+
153+
### Required Front Matter
154+
155+
```yaml
156+
---
157+
layout: analysis
158+
title: "Product Name Analysis"
159+
description: "Concise description for SEO"
160+
permalink: /product-name-analysis/
161+
product_name: "Product Name"
162+
website: "https://product.com"
163+
tags:
164+
- "Tag1"
165+
- "Tag2"
166+
---
167+
```
168+
169+
### Recommended Structure
170+
171+
1. **Overview** - What the product does
172+
2. **Key Features** - Main capabilities
173+
3. **Use Cases** - Ideal scenarios
174+
4. **Pros & Cons** - Balanced assessment
175+
5. **Pricing** - If publicly available
176+
6. **Alternatives** - Similar products
177+
178+
### Writing Tips
179+
180+
- Be objective and factual
181+
- Include specific feature names
182+
- Cite official sources when possible
183+
- Update `last_updated` when making changes
184+
185+
## Creating Tag Pages
186+
187+
### Tag Page Template
188+
189+
```markdown
190+
---
191+
layout: tag_page
192+
tag: "Tag Name"
193+
title: "Tag Name"
194+
description: "Description for SEO"
195+
permalink: /tags/tag-slug/
196+
---
197+
198+
Introduction paragraph about what this tag represents.
199+
```
200+
201+
### Adding Tag Checklists
202+
203+
Edit `_data/tag_checklists.yml`:
204+
205+
```yaml
206+
tag-slug:
207+
- "Checklist item 1"
208+
- "Checklist item 2"
209+
- "Checklist item 3"
210+
```
211+
212+
## Code Style Guidelines
213+
214+
### SCSS
215+
216+
- Use CSS custom properties (variables) from `_variables.scss`
217+
- Follow BEM-like naming: `.block`, `.block-element`, `.block--modifier`
218+
- Keep selectors shallow (max 3 levels)
219+
- Mobile-first media queries
220+
221+
### JavaScript
222+
223+
- Use ES6+ syntax
224+
- Implement debounce for search inputs
225+
- Check for element existence before attaching listeners
226+
- No jQuery dependency
227+
228+
### Liquid Templates
229+
230+
- Escape user-generated content: `{{ value | escape }}`
231+
- Use `{% if %}` guards for optional values
232+
- Prefer includes for repeated HTML
233+
234+
## Submitting Changes
235+
236+
### Before Submitting
237+
238+
1. Run validation: `ruby _scripts/check_site_data.rb`
239+
2. Test locally: `bundle exec jekyll serve`
240+
3. Check mobile responsiveness
241+
4. Verify all links work
242+
243+
### Pull Request Process
244+
245+
1. Fork the repository
246+
2. Create a feature branch: `git checkout -b feature/your-feature`
247+
3. Make your changes
248+
4. Commit with clear messages
249+
5. Push to your fork
250+
6. Open a Pull Request
251+
252+
### Commit Message Format
253+
254+
```
255+
type: brief description
256+
257+
- Detail 1
258+
- Detail 2
259+
```
260+
261+
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`
262+
263+
### Review Criteria
264+
265+
- [ ] Passes validation scripts
266+
- [ ] Follows code style guidelines
267+
- [ ] Mobile-responsive
268+
- [ ] No broken links
269+
- [ ] Clear documentation for new features
270+
271+
## Questions?
272+
273+
- Open an [Issue](https://github.com/Digidai/HireAI/issues)
274+
- Check existing [Discussions](https://github.com/Digidai/HireAI/discussions)
21275
22276
Thank you for contributing!

_config.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ plugins:
1515
- jekyll-feed
1616
- jekyll-sitemap # Explicitly enable sitemap generation
1717

18+
# Sass/SCSS settings
19+
sass:
20+
style: compressed
21+
sass_dir: _sass
22+
1823
# Collections - organize analysis files
1924
collections:
2025
analyses:

_headers

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,25 @@
11
/*
2-
Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; script-src 'self' 'nonce-hireai'; connect-src 'self' https://fonts.googleapis.com https://fonts.gstatic.com; form-action 'self'; upgrade-insecure-requests
2+
Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; style-src 'self' https://fonts.googleapis.com; script-src 'self' https://cdn.jsdelivr.net; connect-src 'self' https://fonts.googleapis.com https://fonts.gstatic.com; form-action 'self'; upgrade-insecure-requests
33
Referrer-Policy: strict-origin-when-cross-origin
44
X-Content-Type-Options: nosniff
55
X-Frame-Options: DENY
6+
X-XSS-Protection: 1; mode=block
67
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()
78
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
89

10+
# Cache static assets for 1 year
11+
/assets/css/*
12+
Cache-Control: public, max-age=31536000, immutable
13+
14+
/assets/js/*
15+
Cache-Control: public, max-age=31536000, immutable
16+
17+
/assets/images/*
18+
Cache-Control: public, max-age=31536000, immutable
19+
20+
# Cache HTML pages for 1 hour
21+
/*.html
22+
Cache-Control: public, max-age=3600
23+
24+
/*/
25+
Cache-Control: public, max-age=3600

0 commit comments

Comments
 (0)