From 8205ae709ccda986f36d22f2d7a7ac2fc2efd8c7 Mon Sep 17 00:00:00 2001 From: ZhuiGuangAI Dev Date: Fri, 2 Oct 2026 18:52:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=A6=96=E6=AC=A1=E6=8E=A8=E9=80=81?= =?UTF-8?q?=E5=88=B0Gitea=20-=20=E5=AE=8C=E6=95=B4=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=20+=20=E5=AE=89=E5=85=A8=E5=8A=A0=E5=9B=BA?= =?UTF-8?q?=20+=20=E7=9F=A5=E8=AF=86=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 4 +- .env | 2 +- .env.example | 12 + .gitignore | 10 + .trae/CHANGELOG | 433 ++ .trae/ai_coding_knowledge.json | 446 ++ .trae/knowledge_graph.json | 457 ++ .trae/knowledge_graph.jsonl | 50 + .trae/rules/README.md | 61 + .trae/rules/ai_agent_rules.md | 88 + .trae/rules/ai_collaboration.md | 110 + .trae/rules/project_rules.md | 160 +- .trae/specs/modules.md | 65 +- .trae/specs/modules/01-database.md | 19 + .trae/specs/modules/02-api.md | 23 + .trae/specs/modules/03-pages.md | 46 +- .../specs/modules/04-components-and-styles.md | 11 + .trae/specs/modules/07-lib-and-scripts.md | 92 +- .trae/specs/modules/08-community.md | 10 + .trae/specs/modules/09-devops.md | 14 +- .trae/specs/modules/17-rules.md | 70 + .trae/specs/modules/notifications.md | 131 + .trae/specs/modules/points.md | 179 + .trae/specs/modules/search.md | 93 + .trae/specs/modules/testing.md | 174 + .trae/specs/modules/theme.md | 118 + .trae/specs/modules/tools.md | 128 + Dockerfile | 9 +- Temp/check-server.sh | 30 - crontab.txt | 80 +- data/bot-characters.json | 5223 +---------------- docker-compose.yml | 18 +- docs/CONTAINERIZATION.md | 1 - next.config.mjs | 24 +- package-lock.json | 2091 ++++++- package.json | 14 +- .../migration.sql | 162 + .../migration.sql | 2 + prisma/schema.prisma | 69 +- public/avatars/adventurer_001.svg | 13 + public/avatars/adventurer_002.svg | 13 + public/avatars/adventurer_003.svg | 13 + public/avatars/adventurer_004.svg | 13 + public/avatars/adventurer_005.svg | 13 + public/avatars/adventurer_006.svg | 13 + public/avatars/adventurer_007.svg | 13 + public/avatars/adventurer_008.svg | 13 + public/avatars/adventurer_009.svg | 13 + public/avatars/adventurer_010.svg | 13 + public/avatars/avataaars_001.svg | 13 + public/avatars/avataaars_002.svg | 13 + public/avatars/avataaars_003.svg | 13 + public/avatars/avataaars_004.svg | 13 + public/avatars/avataaars_005.svg | 13 + public/avatars/avataaars_006.svg | 13 + public/avatars/avataaars_007.svg | 13 + public/avatars/avataaars_008.svg | 13 + public/avatars/avataaars_009.svg | 13 + public/avatars/avataaars_010.svg | 13 + public/avatars/big-smile_001.svg | 13 + public/avatars/big-smile_002.svg | 13 + public/avatars/big-smile_003.svg | 13 + public/avatars/big-smile_004.svg | 13 + public/avatars/big-smile_005.svg | 13 + public/avatars/big-smile_006.svg | 13 + public/avatars/big-smile_007.svg | 13 + public/avatars/big-smile_008.svg | 13 + public/avatars/big-smile_009.svg | 13 + public/avatars/big-smile_010.svg | 13 + public/avatars/bottts-neutral_001.svg | 13 + public/avatars/bottts-neutral_002.svg | 13 + public/avatars/bottts-neutral_003.svg | 13 + public/avatars/bottts-neutral_004.svg | 13 + public/avatars/bottts-neutral_005.svg | 13 + public/avatars/bottts-neutral_006.svg | 13 + public/avatars/bottts-neutral_007.svg | 13 + public/avatars/bottts-neutral_008.svg | 13 + public/avatars/bottts-neutral_009.svg | 13 + public/avatars/bottts-neutral_010.svg | 13 + public/avatars/bottts_001.svg | 13 + public/avatars/bottts_002.svg | 13 + public/avatars/bottts_003.svg | 13 + public/avatars/bottts_004.svg | 13 + public/avatars/bottts_005.svg | 13 + public/avatars/bottts_006.svg | 13 + public/avatars/bottts_007.svg | 13 + public/avatars/bottts_008.svg | 13 + public/avatars/bottts_009.svg | 13 + public/avatars/bottts_010.svg | 13 + public/avatars/croodles_001.svg | 13 + public/avatars/croodles_002.svg | 13 + public/avatars/croodles_003.svg | 13 + public/avatars/croodles_004.svg | 13 + public/avatars/croodles_005.svg | 13 + public/avatars/croodles_006.svg | 13 + public/avatars/croodles_007.svg | 13 + public/avatars/croodles_008.svg | 13 + public/avatars/croodles_009.svg | 13 + public/avatars/croodles_010.svg | 13 + public/avatars/female_business_000.svg | 12 + public/avatars/female_business_001.svg | 12 + public/avatars/female_business_002.svg | 12 + public/avatars/female_business_003.svg | 12 + public/avatars/female_business_004.svg | 12 + public/avatars/female_business_005.svg | 12 + public/avatars/female_business_006.svg | 12 + public/avatars/female_business_007.svg | 12 + public/avatars/female_business_008.svg | 12 + public/avatars/female_business_009.svg | 12 + public/avatars/female_business_010.svg | 12 + public/avatars/female_business_011.svg | 12 + public/avatars/female_business_012.svg | 12 + public/avatars/female_business_013.svg | 12 + public/avatars/female_business_014.svg | 12 + public/avatars/female_business_015.svg | 12 + public/avatars/female_business_016.svg | 12 + public/avatars/female_business_017.svg | 12 + public/avatars/female_business_018.svg | 12 + public/avatars/female_business_019.svg | 12 + public/avatars/female_creative_000.svg | 12 + public/avatars/female_creative_001.svg | 12 + public/avatars/female_creative_002.svg | 12 + public/avatars/female_creative_003.svg | 12 + public/avatars/female_creative_004.svg | 12 + public/avatars/female_creative_005.svg | 12 + public/avatars/female_creative_006.svg | 12 + public/avatars/female_creative_007.svg | 12 + public/avatars/female_creative_008.svg | 12 + public/avatars/female_creative_009.svg | 12 + public/avatars/female_creative_010.svg | 12 + public/avatars/female_creative_011.svg | 12 + public/avatars/female_creative_012.svg | 12 + public/avatars/female_creative_013.svg | 12 + public/avatars/female_creative_014.svg | 12 + public/avatars/female_creative_015.svg | 12 + public/avatars/female_creative_016.svg | 12 + public/avatars/female_creative_017.svg | 12 + public/avatars/female_creative_018.svg | 12 + public/avatars/female_creative_019.svg | 12 + public/avatars/female_creative_020.svg | 12 + public/avatars/female_creative_021.svg | 12 + public/avatars/female_creative_022.svg | 12 + public/avatars/female_creative_023.svg | 12 + public/avatars/female_creative_024.svg | 12 + public/avatars/female_creative_025.svg | 12 + public/avatars/female_creative_026.svg | 12 + public/avatars/female_creative_027.svg | 12 + public/avatars/female_creative_028.svg | 12 + public/avatars/female_creative_029.svg | 12 + public/avatars/female_cute_000.svg | 12 + public/avatars/female_cute_001.svg | 12 + public/avatars/female_cute_002.svg | 12 + public/avatars/female_cute_003.svg | 12 + public/avatars/female_cute_004.svg | 12 + public/avatars/female_cute_005.svg | 12 + public/avatars/female_cute_006.svg | 12 + public/avatars/female_cute_007.svg | 12 + public/avatars/female_cute_008.svg | 12 + public/avatars/female_cute_009.svg | 12 + public/avatars/female_cute_010.svg | 12 + public/avatars/female_cute_011.svg | 12 + public/avatars/female_cute_012.svg | 12 + public/avatars/female_cute_013.svg | 12 + public/avatars/female_cute_014.svg | 12 + public/avatars/female_cute_015.svg | 12 + public/avatars/female_cute_016.svg | 12 + public/avatars/female_cute_017.svg | 12 + public/avatars/female_cute_018.svg | 12 + public/avatars/female_cute_019.svg | 12 + public/avatars/female_cute_020.svg | 12 + public/avatars/female_cute_021.svg | 12 + public/avatars/female_cute_022.svg | 12 + public/avatars/female_cute_023.svg | 12 + public/avatars/female_cute_024.svg | 12 + public/avatars/female_nature_000.svg | 12 + public/avatars/female_nature_001.svg | 12 + public/avatars/female_nature_002.svg | 12 + public/avatars/female_nature_003.svg | 12 + public/avatars/female_nature_004.svg | 12 + public/avatars/female_nature_005.svg | 12 + public/avatars/female_nature_006.svg | 12 + public/avatars/female_nature_007.svg | 12 + public/avatars/female_nature_008.svg | 12 + public/avatars/female_nature_009.svg | 12 + public/avatars/female_nature_010.svg | 12 + public/avatars/female_nature_011.svg | 12 + public/avatars/female_nature_012.svg | 12 + public/avatars/female_nature_013.svg | 12 + public/avatars/female_nature_014.svg | 12 + public/avatars/female_sport_000.svg | 12 + public/avatars/female_sport_001.svg | 12 + public/avatars/female_sport_002.svg | 12 + public/avatars/female_sport_003.svg | 12 + public/avatars/female_sport_004.svg | 12 + public/avatars/female_sport_005.svg | 12 + public/avatars/female_sport_006.svg | 12 + public/avatars/female_sport_007.svg | 12 + public/avatars/female_sport_008.svg | 12 + public/avatars/female_sport_009.svg | 12 + public/avatars/female_sport_010.svg | 12 + public/avatars/female_sport_011.svg | 12 + public/avatars/female_sport_012.svg | 12 + public/avatars/female_sport_013.svg | 12 + public/avatars/female_sport_014.svg | 12 + public/avatars/female_tech_000.svg | 12 + public/avatars/female_tech_001.svg | 12 + public/avatars/female_tech_002.svg | 12 + public/avatars/female_tech_003.svg | 12 + public/avatars/female_tech_004.svg | 12 + public/avatars/female_tech_005.svg | 12 + public/avatars/female_tech_006.svg | 12 + public/avatars/female_tech_007.svg | 12 + public/avatars/female_tech_008.svg | 12 + public/avatars/female_tech_009.svg | 12 + public/avatars/female_tech_010.svg | 12 + public/avatars/female_tech_011.svg | 12 + public/avatars/female_tech_012.svg | 12 + public/avatars/female_tech_013.svg | 12 + public/avatars/female_tech_014.svg | 12 + public/avatars/female_tech_015.svg | 12 + public/avatars/female_tech_016.svg | 12 + public/avatars/female_tech_017.svg | 12 + public/avatars/female_tech_018.svg | 12 + public/avatars/female_tech_019.svg | 12 + public/avatars/fun-emoji_001.svg | 13 + public/avatars/fun-emoji_002.svg | 13 + public/avatars/fun-emoji_003.svg | 13 + public/avatars/fun-emoji_004.svg | 13 + public/avatars/fun-emoji_005.svg | 13 + public/avatars/fun-emoji_006.svg | 13 + public/avatars/fun-emoji_007.svg | 13 + public/avatars/fun-emoji_008.svg | 13 + public/avatars/fun-emoji_009.svg | 13 + public/avatars/fun-emoji_010.svg | 13 + public/avatars/lorelei_001.svg | 13 + public/avatars/lorelei_002.svg | 13 + public/avatars/lorelei_003.svg | 13 + public/avatars/lorelei_004.svg | 13 + public/avatars/lorelei_005.svg | 13 + public/avatars/lorelei_006.svg | 13 + public/avatars/lorelei_007.svg | 13 + public/avatars/lorelei_008.svg | 13 + public/avatars/lorelei_009.svg | 13 + public/avatars/lorelei_010.svg | 13 + public/avatars/male_business_000.svg | 12 + public/avatars/male_business_001.svg | 12 + public/avatars/male_business_002.svg | 12 + public/avatars/male_business_003.svg | 12 + public/avatars/male_business_004.svg | 12 + public/avatars/male_business_005.svg | 12 + public/avatars/male_business_006.svg | 12 + public/avatars/male_business_007.svg | 12 + public/avatars/male_business_008.svg | 12 + public/avatars/male_business_009.svg | 12 + public/avatars/male_business_010.svg | 12 + public/avatars/male_business_011.svg | 12 + public/avatars/male_business_012.svg | 12 + public/avatars/male_business_013.svg | 12 + public/avatars/male_business_014.svg | 12 + public/avatars/male_business_015.svg | 12 + public/avatars/male_business_016.svg | 12 + public/avatars/male_business_017.svg | 12 + public/avatars/male_business_018.svg | 12 + public/avatars/male_business_019.svg | 12 + public/avatars/male_business_020.svg | 12 + public/avatars/male_business_021.svg | 12 + public/avatars/male_business_022.svg | 12 + public/avatars/male_business_023.svg | 12 + public/avatars/male_business_024.svg | 12 + public/avatars/male_business_025.svg | 12 + public/avatars/male_business_026.svg | 12 + public/avatars/male_business_027.svg | 12 + public/avatars/male_business_028.svg | 12 + public/avatars/male_business_029.svg | 12 + public/avatars/male_business_030.svg | 12 + public/avatars/male_business_031.svg | 12 + public/avatars/male_business_032.svg | 12 + public/avatars/male_business_033.svg | 12 + public/avatars/male_business_034.svg | 12 + public/avatars/male_casual_000.svg | 12 + public/avatars/male_casual_001.svg | 12 + public/avatars/male_casual_002.svg | 12 + public/avatars/male_casual_003.svg | 12 + public/avatars/male_casual_004.svg | 12 + public/avatars/male_casual_005.svg | 12 + public/avatars/male_casual_006.svg | 12 + public/avatars/male_casual_007.svg | 12 + public/avatars/male_casual_008.svg | 12 + public/avatars/male_casual_009.svg | 12 + public/avatars/male_casual_010.svg | 12 + public/avatars/male_casual_011.svg | 12 + public/avatars/male_casual_012.svg | 12 + public/avatars/male_casual_013.svg | 12 + public/avatars/male_casual_014.svg | 12 + public/avatars/male_creative_000.svg | 12 + public/avatars/male_creative_001.svg | 12 + public/avatars/male_creative_002.svg | 12 + public/avatars/male_creative_003.svg | 12 + public/avatars/male_creative_004.svg | 12 + public/avatars/male_creative_005.svg | 12 + public/avatars/male_creative_006.svg | 12 + public/avatars/male_creative_007.svg | 12 + public/avatars/male_creative_008.svg | 12 + public/avatars/male_creative_009.svg | 12 + public/avatars/male_creative_010.svg | 12 + public/avatars/male_creative_011.svg | 12 + public/avatars/male_creative_012.svg | 12 + public/avatars/male_creative_013.svg | 12 + public/avatars/male_creative_014.svg | 12 + public/avatars/male_creative_015.svg | 12 + public/avatars/male_creative_016.svg | 12 + public/avatars/male_creative_017.svg | 12 + public/avatars/male_creative_018.svg | 12 + public/avatars/male_creative_019.svg | 12 + public/avatars/male_dark_000.svg | 9 + public/avatars/male_dark_001.svg | 9 + public/avatars/male_dark_002.svg | 9 + public/avatars/male_dark_003.svg | 9 + public/avatars/male_dark_004.svg | 9 + public/avatars/male_dark_005.svg | 9 + public/avatars/male_dark_006.svg | 9 + public/avatars/male_dark_007.svg | 9 + public/avatars/male_dark_008.svg | 9 + public/avatars/male_dark_009.svg | 9 + public/avatars/male_sport_000.svg | 12 + public/avatars/male_sport_001.svg | 12 + public/avatars/male_sport_002.svg | 12 + public/avatars/male_sport_003.svg | 12 + public/avatars/male_sport_004.svg | 12 + public/avatars/male_sport_005.svg | 12 + public/avatars/male_sport_006.svg | 12 + public/avatars/male_sport_007.svg | 12 + public/avatars/male_sport_008.svg | 12 + public/avatars/male_sport_009.svg | 12 + public/avatars/male_sport_010.svg | 12 + public/avatars/male_sport_011.svg | 12 + public/avatars/male_sport_012.svg | 12 + public/avatars/male_sport_013.svg | 12 + public/avatars/male_sport_014.svg | 12 + public/avatars/male_sport_015.svg | 12 + public/avatars/male_sport_016.svg | 12 + public/avatars/male_sport_017.svg | 12 + public/avatars/male_sport_018.svg | 12 + public/avatars/male_sport_019.svg | 12 + public/avatars/male_tech_000.svg | 12 + public/avatars/male_tech_001.svg | 12 + public/avatars/male_tech_002.svg | 12 + public/avatars/male_tech_003.svg | 12 + public/avatars/male_tech_004.svg | 12 + public/avatars/male_tech_005.svg | 12 + public/avatars/male_tech_006.svg | 12 + public/avatars/male_tech_007.svg | 12 + public/avatars/male_tech_008.svg | 12 + public/avatars/male_tech_009.svg | 12 + public/avatars/male_tech_010.svg | 12 + public/avatars/male_tech_011.svg | 12 + public/avatars/male_tech_012.svg | 12 + public/avatars/male_tech_013.svg | 12 + public/avatars/male_tech_014.svg | 12 + public/avatars/male_tech_015.svg | 12 + public/avatars/male_tech_016.svg | 12 + public/avatars/male_tech_017.svg | 12 + public/avatars/male_tech_018.svg | 12 + public/avatars/male_tech_019.svg | 12 + public/avatars/male_tech_020.svg | 12 + public/avatars/male_tech_021.svg | 12 + public/avatars/male_tech_022.svg | 12 + public/avatars/male_tech_023.svg | 12 + public/avatars/male_tech_024.svg | 12 + public/avatars/manifest.json | 1234 ++++ public/avatars/micah_001.svg | 13 + public/avatars/micah_002.svg | 13 + public/avatars/micah_003.svg | 13 + public/avatars/micah_004.svg | 13 + public/avatars/micah_005.svg | 13 + public/avatars/micah_006.svg | 13 + public/avatars/micah_007.svg | 13 + public/avatars/micah_008.svg | 13 + public/avatars/micah_009.svg | 13 + public/avatars/micah_010.svg | 13 + public/avatars/neutral_abstract_000.svg | 9 + public/avatars/neutral_abstract_001.svg | 12 + public/avatars/neutral_abstract_002.svg | 12 + public/avatars/neutral_abstract_003.svg | 12 + public/avatars/neutral_abstract_004.svg | 9 + public/avatars/neutral_abstract_005.svg | 12 + public/avatars/neutral_abstract_006.svg | 12 + public/avatars/neutral_abstract_007.svg | 12 + public/avatars/neutral_abstract_008.svg | 9 + public/avatars/neutral_abstract_009.svg | 12 + public/avatars/neutral_abstract_010.svg | 12 + public/avatars/neutral_abstract_011.svg | 12 + public/avatars/neutral_abstract_012.svg | 9 + public/avatars/neutral_abstract_013.svg | 12 + public/avatars/neutral_abstract_014.svg | 12 + public/avatars/neutral_abstract_015.svg | 12 + public/avatars/neutral_abstract_016.svg | 9 + public/avatars/neutral_abstract_017.svg | 12 + public/avatars/neutral_abstract_018.svg | 12 + public/avatars/neutral_abstract_019.svg | 12 + public/avatars/neutral_abstract_020.svg | 9 + public/avatars/neutral_abstract_021.svg | 12 + public/avatars/neutral_abstract_022.svg | 12 + public/avatars/neutral_abstract_023.svg | 12 + public/avatars/neutral_abstract_024.svg | 9 + public/avatars/neutral_abstract_025.svg | 12 + public/avatars/neutral_abstract_026.svg | 12 + public/avatars/neutral_abstract_027.svg | 12 + public/avatars/neutral_abstract_028.svg | 9 + public/avatars/neutral_abstract_029.svg | 12 + public/avatars/neutral_cute_000.svg | 12 + public/avatars/neutral_cute_001.svg | 12 + public/avatars/neutral_cute_002.svg | 12 + public/avatars/neutral_cute_003.svg | 12 + public/avatars/neutral_cute_004.svg | 12 + public/avatars/neutral_cute_005.svg | 12 + public/avatars/neutral_cute_006.svg | 12 + public/avatars/neutral_cute_007.svg | 12 + public/avatars/neutral_cute_008.svg | 12 + public/avatars/neutral_cute_009.svg | 12 + public/avatars/neutral_cute_010.svg | 12 + public/avatars/neutral_cute_011.svg | 12 + public/avatars/neutral_cute_012.svg | 12 + public/avatars/neutral_cute_013.svg | 12 + public/avatars/neutral_cute_014.svg | 12 + public/avatars/neutral_cute_015.svg | 12 + public/avatars/neutral_cute_016.svg | 12 + public/avatars/neutral_cute_017.svg | 12 + public/avatars/neutral_cute_018.svg | 12 + public/avatars/neutral_cute_019.svg | 12 + public/avatars/neutral_geometric_000.svg | 9 + public/avatars/neutral_geometric_001.svg | 12 + public/avatars/neutral_geometric_002.svg | 12 + public/avatars/neutral_geometric_003.svg | 12 + public/avatars/neutral_geometric_004.svg | 9 + public/avatars/neutral_geometric_005.svg | 12 + public/avatars/neutral_geometric_006.svg | 12 + public/avatars/neutral_geometric_007.svg | 12 + public/avatars/neutral_geometric_008.svg | 9 + public/avatars/neutral_geometric_009.svg | 12 + public/avatars/neutral_geometric_010.svg | 12 + public/avatars/neutral_geometric_011.svg | 12 + public/avatars/neutral_geometric_012.svg | 9 + public/avatars/neutral_geometric_013.svg | 12 + public/avatars/neutral_geometric_014.svg | 12 + public/avatars/neutral_geometric_015.svg | 12 + public/avatars/neutral_geometric_016.svg | 9 + public/avatars/neutral_geometric_017.svg | 12 + public/avatars/neutral_geometric_018.svg | 12 + public/avatars/neutral_geometric_019.svg | 12 + public/avatars/neutral_minimal_000.svg | 12 + public/avatars/neutral_minimal_001.svg | 9 + public/avatars/neutral_minimal_002.svg | 12 + public/avatars/neutral_minimal_003.svg | 12 + public/avatars/neutral_minimal_004.svg | 12 + public/avatars/neutral_minimal_005.svg | 9 + public/avatars/neutral_minimal_006.svg | 12 + public/avatars/neutral_minimal_007.svg | 12 + public/avatars/neutral_minimal_008.svg | 12 + public/avatars/neutral_minimal_009.svg | 9 + public/avatars/neutral_minimal_010.svg | 12 + public/avatars/neutral_minimal_011.svg | 12 + public/avatars/neutral_minimal_012.svg | 12 + public/avatars/neutral_minimal_013.svg | 9 + public/avatars/neutral_minimal_014.svg | 12 + public/avatars/neutral_minimal_015.svg | 12 + public/avatars/neutral_minimal_016.svg | 12 + public/avatars/neutral_minimal_017.svg | 9 + public/avatars/neutral_minimal_018.svg | 12 + public/avatars/neutral_minimal_019.svg | 12 + public/avatars/neutral_minimal_020.svg | 12 + public/avatars/neutral_minimal_021.svg | 9 + public/avatars/neutral_minimal_022.svg | 12 + public/avatars/neutral_minimal_023.svg | 12 + public/avatars/neutral_minimal_024.svg | 12 + public/avatars/neutral_nature_000.svg | 12 + public/avatars/neutral_nature_001.svg | 12 + public/avatars/neutral_nature_002.svg | 12 + public/avatars/neutral_nature_003.svg | 12 + public/avatars/neutral_nature_004.svg | 12 + public/avatars/neutral_nature_005.svg | 12 + public/avatars/neutral_nature_006.svg | 12 + public/avatars/neutral_nature_007.svg | 12 + public/avatars/neutral_nature_008.svg | 12 + public/avatars/neutral_nature_009.svg | 12 + public/avatars/neutral_nature_010.svg | 12 + public/avatars/neutral_nature_011.svg | 12 + public/avatars/neutral_nature_012.svg | 12 + public/avatars/neutral_nature_013.svg | 12 + public/avatars/neutral_nature_014.svg | 12 + public/avatars/neutral_nature_015.svg | 12 + public/avatars/neutral_nature_016.svg | 12 + public/avatars/neutral_nature_017.svg | 12 + public/avatars/neutral_nature_018.svg | 12 + public/avatars/neutral_nature_019.svg | 12 + public/avatars/neutral_nature_020.svg | 12 + public/avatars/neutral_nature_021.svg | 12 + public/avatars/neutral_nature_022.svg | 12 + public/avatars/neutral_nature_023.svg | 12 + public/avatars/neutral_nature_024.svg | 12 + public/avatars/neutral_retro_000.svg | 12 + public/avatars/neutral_retro_001.svg | 12 + public/avatars/neutral_retro_002.svg | 12 + public/avatars/neutral_retro_003.svg | 12 + public/avatars/neutral_retro_004.svg | 12 + public/avatars/neutral_retro_005.svg | 12 + public/avatars/neutral_retro_006.svg | 12 + public/avatars/neutral_retro_007.svg | 12 + public/avatars/neutral_retro_008.svg | 12 + public/avatars/neutral_retro_009.svg | 12 + public/avatars/neutral_retro_010.svg | 12 + public/avatars/neutral_retro_011.svg | 12 + public/avatars/neutral_retro_012.svg | 12 + public/avatars/neutral_retro_013.svg | 12 + public/avatars/neutral_retro_014.svg | 12 + public/avatars/neutral_retro_015.svg | 12 + public/avatars/neutral_retro_016.svg | 12 + public/avatars/neutral_retro_017.svg | 12 + public/avatars/neutral_retro_018.svg | 12 + public/avatars/neutral_retro_019.svg | 12 + public/avatars/neutral_space_000.svg | 9 + public/avatars/neutral_space_001.svg | 9 + public/avatars/neutral_space_002.svg | 9 + public/avatars/neutral_space_003.svg | 9 + public/avatars/neutral_space_004.svg | 9 + public/avatars/neutral_space_005.svg | 9 + public/avatars/neutral_space_006.svg | 9 + public/avatars/neutral_space_007.svg | 9 + public/avatars/neutral_space_008.svg | 9 + public/avatars/neutral_space_009.svg | 9 + public/avatars/neutral_space_010.svg | 9 + public/avatars/neutral_space_011.svg | 9 + public/avatars/neutral_space_012.svg | 9 + public/avatars/neutral_space_013.svg | 9 + public/avatars/neutral_space_014.svg | 9 + public/avatars/neutral_space_015.svg | 9 + public/avatars/neutral_space_016.svg | 9 + public/avatars/neutral_space_017.svg | 9 + public/avatars/neutral_space_018.svg | 9 + public/avatars/neutral_space_019.svg | 9 + public/avatars/notionists_001.svg | 13 + public/avatars/notionists_002.svg | 13 + public/avatars/notionists_003.svg | 13 + public/avatars/notionists_004.svg | 13 + public/avatars/notionists_005.svg | 13 + public/avatars/notionists_006.svg | 13 + public/avatars/notionists_007.svg | 13 + public/avatars/notionists_008.svg | 13 + public/avatars/notionists_009.svg | 13 + public/avatars/notionists_010.svg | 13 + public/avatars/open-peeps_001.svg | 13 + public/avatars/open-peeps_002.svg | 13 + public/avatars/open-peeps_003.svg | 13 + public/avatars/open-peeps_004.svg | 13 + public/avatars/open-peeps_005.svg | 13 + public/avatars/open-peeps_006.svg | 13 + public/avatars/open-peeps_007.svg | 13 + public/avatars/open-peeps_008.svg | 13 + public/avatars/open-peeps_009.svg | 13 + public/avatars/open-peeps_010.svg | 13 + public/avatars/pixel-art_001.svg | 13 + public/avatars/pixel-art_002.svg | 13 + public/avatars/pixel-art_003.svg | 13 + public/avatars/pixel-art_004.svg | 13 + public/avatars/pixel-art_005.svg | 13 + public/avatars/pixel-art_006.svg | 13 + public/avatars/pixel-art_007.svg | 13 + public/avatars/pixel-art_008.svg | 13 + public/avatars/pixel-art_009.svg | 13 + public/avatars/pixel-art_010.svg | 13 + public/bot-avatars/ai_critic.svg | 55 +- public/bot-avatars/ai_dev.svg | 22 +- public/bot-avatars/ai_investor.svg | 55 +- public/bot-avatars/ai_news.svg | 55 +- public/bot-avatars/ai_observer.svg | 40 +- public/bot-avatars/ai_pm.svg | 47 +- public/bot-avatars/ai_problem.svg | 43 +- public/bot-avatars/ai_student.svg | 55 +- public/bot-avatars/ajie.svg | 47 +- public/bot-avatars/atie.svg | 47 +- public/bot-avatars/awei.svg | 43 +- public/bot-avatars/cb_amazon.svg | 40 +- public/bot-avatars/cb_expat.svg | 47 +- public/bot-avatars/cb_news.svg | 40 +- public/bot-avatars/cb_observer.svg | 43 +- public/bot-avatars/cb_problem.svg | 47 +- public/bot-avatars/cb_thinker.svg | 43 +- public/bot-avatars/chengjie.svg | 40 +- public/bot-avatars/ct_creator.svg | 47 +- public/bot-avatars/ct_news.svg | 47 +- public/bot-avatars/ct_observer.svg | 37 +- public/bot-avatars/ct_podcaster.svg | 55 +- public/bot-avatars/ct_problem.svg | 47 +- public/bot-avatars/ct_viewer.svg | 47 +- public/bot-avatars/ct_writer.svg | 55 +- public/bot-avatars/daliu.svg | 55 +- public/bot-avatars/duoduo.svg | 55 +- public/bot-avatars/ec_consumer.svg | 43 +- public/bot-avatars/ec_data_nerd.svg | 43 +- public/bot-avatars/ec_employee.svg | 47 +- public/bot-avatars/ec_news.svg | 40 +- public/bot-avatars/ec_observer.svg | 55 +- public/bot-avatars/ec_problem.svg | 43 +- public/bot-avatars/ec_quitter.svg | 43 +- public/bot-avatars/ec_veteran.svg | 40 +- public/bot-avatars/edu_abroad_alumni.svg | 47 +- public/bot-avatars/edu_abroad_problem.svg | 47 +- public/bot-avatars/edu_anxious_parent.svg | 47 +- public/bot-avatars/edu_news.svg | 25 +- public/bot-avatars/edu_observer.svg | 47 +- public/bot-avatars/edu_problem.svg | 55 +- public/bot-avatars/edu_worker.svg | 40 +- public/bot-avatars/fangchan.svg | 43 +- public/bot-avatars/fd_diner.svg | 43 +- public/bot-avatars/fd_news.svg | 55 +- public/bot-avatars/fd_observer.svg | 55 +- public/bot-avatars/fd_problem.svg | 47 +- public/bot-avatars/fd_supply_news.svg | 40 +- public/bot-avatars/fd_worker.svg | 47 +- public/bot-avatars/fengkuang.svg | 47 +- public/bot-avatars/fi_industry.svg | 43 +- public/bot-avatars/fi_investor.svg | 43 +- public/bot-avatars/fi_loser.svg | 47 +- public/bot-avatars/fi_newbie.svg | 47 +- public/bot-avatars/fi_news.svg | 55 +- public/bot-avatars/fi_observer.svg | 47 +- public/bot-avatars/fi_problem.svg | 47 +- public/bot-avatars/helaoshi.svg | 47 +- public/bot-avatars/hl_elderly.svg | 47 +- public/bot-avatars/hl_news.svg | 40 +- public/bot-avatars/hl_observer.svg | 43 +- public/bot-avatars/hl_problem.svg | 47 +- public/bot-avatars/hl_young.svg | 40 +- public/bot-avatars/huajie.svg | 55 +- public/bot-avatars/hw_observer.svg | 40 +- public/bot-avatars/jiangnan.svg | 43 +- public/bot-avatars/jiejie.svg | 47 +- public/bot-avatars/jige.svg | 47 +- public/bot-avatars/jike.svg | 47 +- public/bot-avatars/kaige.svg | 43 +- public/bot-avatars/kangshifu.svg | 25 +- public/bot-avatars/laochen.svg | 47 +- public/bot-avatars/laolin.svg | 55 +- public/bot-avatars/laowang.svg | 47 +- public/bot-avatars/laozhang.svg | 40 +- public/bot-avatars/laozhao.svg | 43 +- public/bot-avatars/lily.svg | 40 +- public/bot-avatars/lisa.svg | 55 +- public/bot-avatars/liuqing.svg | 47 +- public/bot-avatars/ll_news.svg | 55 +- public/bot-avatars/ll_observer.svg | 43 +- public/bot-avatars/ll_parent.svg | 47 +- public/bot-avatars/ll_pet.svg | 47 +- public/bot-avatars/ll_problem.svg | 43 +- public/bot-avatars/manifest.json | 648 +- public/bot-avatars/maoge.svg | 29 +- public/bot-avatars/meijie.svg | 47 +- public/bot-avatars/meili.svg | 55 +- public/bot-avatars/nainai.svg | 40 +- public/bot-avatars/paopao.svg | 55 +- .../passerby_ai-tech_comparer_62.svg | 37 + .../passerby_ai-tech_enthusiast_32.svg | 52 + .../passerby_ai-tech_learner_52.svg | 37 + .../bot-avatars/passerby_ai-tech_newbie_2.svg | 52 + .../passerby_ai-tech_observer_12.svg | 44 + .../passerby_ai-tech_questioner_22.svg | 44 + .../passerby_ai-tech_skeptic_42.svg | 40 + .../passerby_career_comparer_63.svg | 44 + .../passerby_career_enthusiast_33.svg | 52 + .../passerby_career_learner_53.svg | 37 + .../bot-avatars/passerby_career_newbie_3.svg | 44 + .../passerby_career_observer_13.svg | 44 + .../passerby_career_questioner_23.svg | 37 + .../passerby_career_skeptic_43.svg | 44 + .../passerby_content_enthusiast_36.svg | 37 + .../passerby_content_learner_56.svg | 44 + .../bot-avatars/passerby_content_newbie_6.svg | 37 + .../passerby_content_observer_16.svg | 44 + .../passerby_content_questioner_26.svg | 52 + .../passerby_content_skeptic_46.svg | 44 + .../passerby_cross-border_comparer_64.svg | 37 + .../passerby_cross-border_enthusiast_34.svg | 44 + .../passerby_cross-border_learner_54.svg | 44 + .../passerby_cross-border_newbie_4.svg | 40 + .../passerby_cross-border_observer_14.svg | 44 + .../passerby_cross-border_questioner_24.svg | 37 + .../passerby_cross-border_skeptic_44.svg | 44 + .../passerby_ecommerce_comparer_61.svg | 37 + .../passerby_ecommerce_enthusiast_31.svg | 52 + .../passerby_ecommerce_learner_51.svg | 44 + .../passerby_ecommerce_newbie_1.svg | 52 + .../passerby_ecommerce_observer_11.svg | 37 + .../passerby_ecommerce_questioner_21.svg | 37 + .../passerby_ecommerce_skeptic_41.svg | 40 + .../passerby_education_enthusiast_38.svg | 37 + .../passerby_education_learner_58.svg | 40 + .../passerby_education_newbie_8.svg | 37 + .../passerby_education_observer_18.svg | 40 + .../passerby_education_questioner_28.svg | 37 + .../passerby_education_skeptic_48.svg | 37 + .../passerby_fire-life_enthusiast_39.svg | 40 + .../passerby_fire-life_learner_59.svg | 44 + .../passerby_fire-life_newbie_9.svg | 52 + .../passerby_fire-life_observer_19.svg | 44 + .../passerby_fire-life_questioner_29.svg | 44 + .../passerby_fire-life_skeptic_49.svg | 52 + .../passerby_money_comparer_60.svg | 40 + .../passerby_money_enthusiast_30.svg | 52 + .../bot-avatars/passerby_money_learner_50.svg | 44 + .../bot-avatars/passerby_money_newbie_0.svg | 44 + .../passerby_money_observer_10.svg | 40 + .../passerby_money_questioner_20.svg | 40 + .../bot-avatars/passerby_money_skeptic_40.svg | 52 + .../passerby_offline-biz_enthusiast_37.svg | 40 + .../passerby_offline-biz_learner_57.svg | 40 + .../passerby_offline-biz_newbie_7.svg | 44 + .../passerby_offline-biz_observer_17.svg | 44 + .../passerby_offline-biz_questioner_27.svg | 44 + .../passerby_offline-biz_skeptic_47.svg | 44 + .../passerby_real-estate_comparer_65.svg | 44 + .../passerby_real-estate_enthusiast_35.svg | 37 + .../passerby_real-estate_learner_55.svg | 44 + .../passerby_real-estate_newbie_5.svg | 37 + .../passerby_real-estate_observer_15.svg | 52 + .../passerby_real-estate_questioner_25.svg | 44 + .../passerby_real-estate_skeptic_45.svg | 44 + public/bot-avatars/qianjie.svg | 43 +- public/bot-avatars/re_buyer.svg | 55 +- public/bot-avatars/re_decorator.svg | 22 +- public/bot-avatars/re_news.svg | 47 +- public/bot-avatars/re_observer.svg | 40 +- public/bot-avatars/re_problem.svg | 47 +- public/bot-avatars/re_renter.svg | 37 +- public/bot-avatars/shengge.svg | 47 +- public/bot-avatars/tangren.svg | 47 +- public/bot-avatars/tiege.svg | 47 +- public/bot-avatars/upzhu.svg | 22 +- public/bot-avatars/wujie.svg | 47 +- public/bot-avatars/wuliu.svg | 55 +- public/bot-avatars/xianyu.svg | 47 +- public/bot-avatars/xiaodao.svg | 55 +- public/bot-avatars/xiaolin.svg | 47 +- public/bot-avatars/xiaoming.svg | 40 +- public/bot-avatars/xiaoyu.svg | 47 +- public/bot-avatars/xiaozhen.svg | 40 +- public/bot-avatars/yingxiao.svg | 29 +- public/bot-avatars/youyu.svg | 55 +- public/bot-avatars/zhongzong.svg | 55 +- public/bot-avatars/zhuangjie.svg | 47 +- public/manifest.json | 25 + public/sw.js | 33 + scripts/_forum-clear.cjs | 70 + scripts/_inspection.sh | 114 - scripts/_rebuild-avatars.mjs | 113 + scripts/auto-review.mjs | 2 +- scripts/backup-volumes.sh | 118 +- scripts/bot-activity.mjs | 358 +- scripts/bot-feedback-loop.mjs | 50 +- scripts/bot-roundtable.mjs | 778 +++ scripts/bot-skill-crystallize.mjs | 7 +- scripts/bot-weekly-review.mjs | 7 +- scripts/check-api.mjs | 45 - scripts/check-categories.cjs | 14 - scripts/check-community.py | 48 - scripts/check-coverage.mjs | 18 - scripts/check-forum.mjs | 40 - scripts/check-html-detail.py | 33 - scripts/check-html.py | 10 - scripts/check-industry.mjs | 27 - scripts/check-memories.mjs | 30 - scripts/check-parents.mjs | 33 - scripts/check-render.py | 41 - scripts/check-slugs.py | 7 - scripts/cleanup-non-ai.mjs | 55 - scripts/cleanup-old-forums.mjs | 73 - scripts/competitor-monitor.mjs | 92 + scripts/cron-daily-discover.sh | 8 - scripts/cron-daily-news.sh | 8 - scripts/cron-task1.sh | 5 - scripts/cron-wrapper.sh | 40 - scripts/daily-discover.mjs | 202 +- scripts/daily-news.mjs | 32 +- scripts/debug-html.py | 27 - scripts/debug-json.mjs | 64 - scripts/debug-rsc.py | 33 - scripts/debug-section.py | 29 - scripts/delete-drafts.mjs | 21 - scripts/deploy-build.sh | 9 + scripts/deploy-cron.sh | 29 + scripts/deploy-run.sh | 29 + scripts/enrich-tool-data.mjs | 247 + scripts/entrypoint-app.sh | 13 +- scripts/entrypoint-cron.sh | 139 +- scripts/final-check.py | 36 - scripts/find-chunks.py | 33 - scripts/find-section.py | 25 - scripts/fix-db-url.cjs | 36 - scripts/fix-db-url.sh | 16 - scripts/fix-task3-data.mjs | 2 +- scripts/fix-ts-types.cjs | 45 - scripts/generate-avatar-library.mjs | 482 ++ scripts/generate-bot-content.mjs | 7 +- scripts/generate-diverse-avatars.mjs | 383 ++ scripts/generate-passerby-roles.mjs | 442 ++ scripts/generate-review-content.mjs | 2 +- scripts/grant-freeze-cards.mjs | 90 + scripts/health-check.mjs | 78 +- scripts/industry-daily.mjs | 480 ++ scripts/industry-thinktank.mjs | 748 +++ scripts/install-cron.sh | 102 - scripts/lib/bot-adversarial-learning.mjs | 7 +- scripts/lib/bot-avatar-generator.mjs | 107 +- scripts/lib/bot-persona.mjs | 16 +- scripts/lib/chinese-text.mjs | 35 + scripts/lib/logger.mjs | 42 + scripts/lib/redis-cache.mjs | 2 +- scripts/lib/reply-quality.mjs | 115 + scripts/lib/retry.mjs | 37 +- scripts/lib/task-runner.mjs | 96 + scripts/lib/topic-diversity.mjs | 83 + scripts/newsletter-generate.mjs | 305 + scripts/notification-digest.mjs | 185 + scripts/parse-rsc.py | 24 - scripts/parse-rsc2.py | 30 - scripts/prompts/bot-activity.txt | 12 + scripts/prompts/bot-feedback.txt | 10 + scripts/prompts/bot-roundtable.txt | 11 + scripts/render-test.py | 41 - scripts/seed-task-configs.mjs | 112 +- scripts/task1-discover-tools.mjs | 30 +- scripts/task3-check-tools.mjs | 29 +- scripts/task6-review-hot.mjs | 2 +- scripts/test-bot-stats.mjs | 94 - scripts/test-content-generation.mjs | 2 +- scripts/test-deepseek.mjs | 2 +- scripts/test-github.mjs | 39 - scripts/test-html.sh | 9 - scripts/test_login.py | 40 - scripts/test_login2.py | 59 - scripts/test_login3.py | 53 - scripts/test_login4.py | 44 - scripts/test_login5.py | 41 - scripts/trend-alert.mjs | 160 + scripts/update-knowledge.mjs | 364 ++ scripts/verify-deploy-docker.sh | 121 + scripts/verify-deploy.sh | 27 - scripts/verify-fix.py | 25 - scripts/weekly-recommend-email.mjs | 762 +++ .../BotAdversarialLearningClient.tsx | 3 +- .../admin/bot-adversarial-learning/page.tsx | 5 +- src/app/(admin)/admin/bot-analytics/page.tsx | 5 +- .../bot-experiments/BotExperimentsClient.tsx | 5 +- .../(admin)/admin/bot-experiments/page.tsx | 5 +- .../admin/bot-quality/BotQualityClient.tsx | 557 ++ src/app/(admin)/admin/bot-quality/page.tsx | 20 + src/app/(admin)/admin/check-tools/page.tsx | 3 +- .../admin/forum/topics/TopicsClient.tsx | 2 +- src/app/(admin)/admin/layout.tsx | 3 +- src/app/(admin)/admin/login/page.tsx | 3 +- src/app/(admin)/admin/page.tsx | 21 + src/app/(admin)/admin/pending-skills/page.tsx | 4 +- src/app/(admin)/admin/pending/page.tsx | 6 +- src/app/(admin)/admin/skills/page.tsx | 15 +- src/app/(admin)/admin/tasks/page.tsx | 73 +- src/app/(admin)/admin/tools/page.tsx | 62 +- src/app/(admin)/admin/update-skills/page.tsx | 87 +- src/app/(developers)/developers/error.tsx | 28 + src/app/(developers)/developers/page.tsx | 393 ++ src/app/(developers)/layout.tsx | 44 + src/app/HomePageClient.tsx | 130 +- src/app/api/admin/bot-quality/route.ts | 63 + .../admin/bots/adversarial-learning/route.ts | 11 +- .../bots/adversarial-learning/run/route.ts | 11 +- src/app/api/admin/bots/experiments/route.ts | 11 +- .../api/admin/bots/experiments/run/route.ts | 11 +- .../admin/bots/experiments/variants/route.ts | 16 +- src/app/api/admin/bots/stats/route.ts | 11 +- src/app/api/admin/categories/[id]/route.ts | 16 +- src/app/api/admin/categories/route.ts | 16 +- src/app/api/admin/check-tools/[id]/route.ts | 11 +- src/app/api/admin/check-tools/route.ts | 11 +- src/app/api/admin/daily-reports/[id]/route.ts | 21 +- .../api/admin/daily-reports/generate/route.ts | 10 +- src/app/api/admin/daily-reports/route.ts | 16 +- src/app/api/admin/discover-news/route.ts | 16 +- src/app/api/admin/discover-skills/route.ts | 11 +- .../api/admin/discover-skills/run/route.ts | 11 +- src/app/api/admin/discover-tools/route.ts | 11 +- .../admin/forum/posts/[id]/moderate/route.ts | 2 + .../admin/forum/reports/[id]/resolve/route.ts | 2 + src/app/api/admin/forum/reports/route.ts | 2 + .../admin/forum/topics/[id]/moderate/route.ts | 2 + src/app/api/admin/forum/topics/route.ts | 2 + src/app/api/admin/migrate-logos/route.ts | 11 +- src/app/api/admin/overview/route.ts | 88 + .../pending-skills/[id]/publish/route.ts | 11 +- .../api/admin/pending-skills/[id]/route.ts | 16 +- .../pending-skills/batch-publish/route.ts | 11 +- .../pending-skills/batch-reject/route.ts | 11 +- .../api/admin/pending-skills/batch/route.ts | 11 +- .../admin/pending-skills/publish-all/route.ts | 11 +- src/app/api/admin/pending-skills/route.ts | 11 +- .../api/admin/pending/[id]/publish/route.ts | 11 +- src/app/api/admin/pending/[id]/route.ts | 16 +- .../api/admin/pending/batch-publish/route.ts | 11 +- .../api/admin/pending/batch-reject/route.ts | 11 +- src/app/api/admin/pending/batch/route.ts | 11 +- .../api/admin/pending/fetch-logos/route.ts | 11 +- src/app/api/admin/pending/route.ts | 11 +- src/app/api/admin/permissions/route.ts | 12 +- .../api/admin/reviews/[id]/generate/route.ts | 4 +- src/app/api/admin/reviews/[id]/route.ts | 21 +- src/app/api/admin/reviews/route.ts | 11 +- src/app/api/admin/roles/[id]/route.ts | 17 +- src/app/api/admin/roles/route.ts | 17 +- .../api/admin/skill-categories/[id]/route.ts | 16 +- src/app/api/admin/skill-categories/route.ts | 16 +- src/app/api/admin/skills/[id]/route.ts | 16 +- src/app/api/admin/skills/route.ts | 11 +- src/app/api/admin/system-config/route.ts | 16 +- src/app/api/admin/tasks/configs/route.ts | 17 +- src/app/api/admin/tasks/logs/route.ts | 12 +- src/app/api/admin/tasks/run/route.ts | 12 +- src/app/api/admin/tools/[id]/route.ts | 16 +- src/app/api/admin/tools/route.ts | 16 +- src/app/api/admin/tools/verify/route.ts | 108 + src/app/api/admin/update-stars/route.ts | 52 +- src/app/api/admin/user-permissions/route.ts | 12 +- src/app/api/auth/[...nextauth]/route.ts | 6 + src/app/api/auth/register/route.ts | 11 +- src/app/api/bot/[id]/route.ts | 3 +- src/app/api/bot/leaderboard/route.ts | 11 +- src/app/api/bots/route.ts | 11 +- src/app/api/categories/route.ts | 16 +- src/app/api/comments/[id]/like/route.ts | 6 + src/app/api/comments/route.ts | 366 +- .../community/checkin-leaderboard/route.ts | 81 + src/app/api/community/hot/route.ts | 101 + src/app/api/community/leaderboard/route.ts | 112 + src/app/api/daily-reports/route.ts | 11 +- src/app/api/feedback/route.ts | 42 + src/app/api/forum/achievements/route.ts | 2 + src/app/api/forum/bookmarks/route.ts | 6 + .../api/forum/categories/[id]/follow/route.ts | 6 + src/app/api/forum/categories/route.ts | 33 +- src/app/api/forum/checkin/route.ts | 2 + src/app/api/forum/drafts/route.ts | 6 + src/app/api/forum/posts/[postId]/tip/route.ts | 2 + src/app/api/forum/reports/route.ts | 6 + src/app/api/forum/search/route.ts | 6 + src/app/api/forum/tags/[slug]/route.ts | 6 + src/app/api/forum/tags/route.ts | 47 +- .../api/forum/topics/[id]/bookmark/route.ts | 6 + .../api/forum/topics/[id]/follow-up/route.ts | 6 +- src/app/api/forum/topics/[id]/like/route.ts | 6 + .../[id]/posts/[postId]/answer/route.ts | 6 + .../topics/[id]/posts/[postId]/like/route.ts | 6 + .../forum/topics/[id]/posts/[postId]/route.ts | 6 + src/app/api/forum/topics/[id]/posts/route.ts | 487 +- src/app/api/forum/topics/[id]/react/route.ts | 2 + src/app/api/forum/topics/[id]/route.ts | 6 + .../forum/topics/[id]/subscription/route.ts | 2 + src/app/api/forum/topics/route.ts | 343 +- src/app/api/health/route.ts | 2 + src/app/api/homepage/route.ts | 171 +- src/app/api/metrics/route.ts | 60 + src/app/api/newsletter/latest/route.ts | 32 + src/app/api/notifications/route.ts | 6 + src/app/api/recommendations/route.ts | 11 +- src/app/api/reviews/route.ts | 6 + src/app/api/rss/route.ts | 72 + src/app/api/search/suggest/route.ts | 157 + src/app/api/shop/items/route.ts | 42 + src/app/api/shop/my-items/route.ts | 66 + src/app/api/shop/purchase/route.ts | 92 + src/app/api/skill-categories/route.ts | 26 +- src/app/api/skill-reviews/rankings/route.ts | 12 +- src/app/api/skill-reviews/route.ts | 11 +- src/app/api/skills/[slug]/review/route.ts | 11 +- src/app/api/skills/[slug]/route.ts | 11 +- src/app/api/skills/elo-battle/route.ts | 190 + src/app/api/skills/elo-categories/route.ts | 38 + src/app/api/skills/elo-rankings/route.ts | 47 + src/app/api/skills/route.ts | 11 +- src/app/api/skills/similar/route.ts | 103 + src/app/api/stats/route.ts | 58 + src/app/api/tools/[slug]/route.ts | 11 +- src/app/api/tools/route.ts | 11 +- src/app/api/tools/similar/route.ts | 103 + src/app/api/tools/verified/route.ts | 38 + src/app/api/user/[id]/activity/route.ts | 11 +- src/app/api/user/[id]/bookmarks/route.ts | 11 +- src/app/api/user/[id]/comments/route.ts | 11 +- src/app/api/user/[id]/posts/route.ts | 11 +- src/app/api/user/[id]/profile/route.ts | 11 +- src/app/api/user/[id]/topics/route.ts | 11 +- src/app/api/user/achievements/route.ts | 189 + src/app/api/user/api-keys/[id]/route.ts | 52 + src/app/api/user/api-keys/route.ts | 94 + src/app/api/user/avatar/upload/route.ts | 63 + src/app/api/user/avatars/route.ts | 71 + src/app/api/user/check-in/route.ts | 185 + .../collections/[id]/items/[itemId]/route.ts | 6 + .../api/user/collections/[id]/items/route.ts | 6 + src/app/api/user/collections/[id]/route.ts | 6 + src/app/api/user/collections/route.ts | 6 + src/app/api/user/favorites/route.ts | 21 +- src/app/api/user/favorites/status/route.ts | 6 + src/app/api/user/history/route.ts | 16 +- src/app/api/user/notification-prefs/route.ts | 108 + src/app/api/user/onboarding/progress/route.ts | 144 + src/app/api/user/points/route.ts | 6 + src/app/api/user/profile/route.ts | 16 +- src/app/api/user/rankings/route.ts | 7 +- src/app/api/user/streak-freeze/route.ts | 20 + src/app/api/user/streak-freeze/use/route.ts | 28 + src/app/api/users/search/route.ts | 6 + .../api/v1/collections/[publicSlug]/route.ts | 23 + src/app/api/v1/collections/route.ts | 64 + src/app/api/v1/search/route.ts | 134 + src/app/api/v1/skills/[slug]/route.ts | 23 + src/app/api/v1/skills/route.ts | 79 + src/app/api/v1/tools/[slug]/route.ts | 23 + src/app/api/v1/tools/route.ts | 78 + src/app/categories/[slug]/CategoryContent.tsx | 28 +- src/app/categories/[slug]/page.tsx | 31 +- src/app/collections/[publicSlug]/error.tsx | 28 + src/app/collections/[publicSlug]/loading.tsx | 42 + src/app/collections/[publicSlug]/page.tsx | 209 + src/app/collections/error.tsx | 28 + src/app/collections/loading.tsx | 42 + src/app/collections/page.tsx | 136 + src/app/community/CommunityRankings.tsx | 328 +- src/app/community/[category]/page.tsx | 2 +- src/app/community/bots/BotsListClient.tsx | 10 +- .../bots/leaderboard/LeaderboardClient.tsx | 780 ++- src/app/community/bots/leaderboard/page.tsx | 4 +- src/app/community/bots/page.tsx | 6 +- src/app/community/checkin/page.tsx | 245 +- src/app/community/error.tsx | 17 + src/app/community/loading.tsx | 10 + src/app/community/page.tsx | 56 +- src/app/community/tag/[slug]/page.tsx | 2 +- src/app/community/tags/page.tsx | 3 +- src/app/community/topic/[id]/ReplyForm.tsx | 77 +- src/app/community/topic/[id]/page.tsx | 69 +- src/app/daily/DailyContent.tsx | 521 ++ src/app/daily/error.tsx | 37 + src/app/daily/loading.tsx | 18 + src/app/daily/page.tsx | 579 +- src/app/error.tsx | 44 +- src/app/global-error.tsx | 74 + src/app/globals.css | 43 +- src/app/layout.tsx | 113 +- src/app/loading.tsx | 10 +- src/app/login/error.tsx | 28 + src/app/login/loading.tsx | 44 + src/app/newsletter/error.tsx | 28 + src/app/newsletter/loading.tsx | 108 + src/app/newsletter/page.tsx | 336 ++ src/app/not-found.tsx | 32 +- src/app/notifications/page.tsx | 401 ++ src/app/page.tsx | 24 +- src/app/reviews/error.tsx | 37 + src/app/reviews/loading.tsx | 18 + src/app/shop/error.tsx | 28 + src/app/shop/layout.tsx | 14 + src/app/shop/loading.tsx | 62 + src/app/shop/page.tsx | 297 + src/app/sitemap.ts | 81 +- src/app/skills/SkillsPageClient.tsx | 170 +- src/app/skills/[slug]/page.tsx | 155 +- src/app/skills/battle/page.tsx | 631 ++ .../skills/compare/CompareFavoritesPicker.tsx | 179 + src/app/skills/compare/page.tsx | 643 ++ src/app/skills/error.tsx | 37 + src/app/skills/loading.tsx | 10 + src/app/skills/page.tsx | 2 + src/app/tools/ToolsContent.tsx | 389 +- src/app/tools/[slug]/page.tsx | 199 +- .../tools/compare/CompareFavoritesPicker.tsx | 179 + src/app/tools/compare/page.tsx | 701 +++ src/app/tools/error.tsx | 37 + src/app/tools/loading.tsx | 12 + src/app/tools/page.tsx | 74 +- src/app/user/[id]/UserPublicProfile.tsx | 11 +- src/app/user/[id]/page.tsx | 60 +- src/app/user/collections/[id]/page.tsx | 676 +-- src/app/user/collections/page.tsx | 19 +- src/app/user/favorites/page.tsx | 61 +- src/app/user/page.tsx | 339 +- src/components/admin/OverviewDashboard.tsx | 247 + src/components/admin/TaskStatsSummary.tsx | 109 + src/components/common/ApiPlayground.tsx | 211 + src/components/common/BackToTop.tsx | 34 + src/components/common/CategorySidebar.tsx | 1 + .../common/CollectionShareToggle.tsx | 124 + src/components/common/CommentCard.tsx | 7 +- src/components/common/CommentThread.tsx | 2 +- src/components/common/CompareBar.tsx | 115 + src/components/common/CompareButton.tsx | 71 + src/components/common/CompareProvider.tsx | 133 + src/components/common/CompareRemoveButton.tsx | 40 + src/components/common/FeedbackButton.tsx | 160 + src/components/common/HighlightText.tsx | 47 + src/components/common/LevelProgressMini.tsx | 51 + .../common/PersonalizedRecommend.tsx | 108 + src/components/common/ReadingProgress.tsx | 29 + src/components/common/ReviewSection.tsx | 5 +- src/components/common/ScreenshotGallery.tsx | 103 + src/components/common/ShareButton.tsx | 3 +- src/components/common/SimilarSkills.tsx | 140 + src/components/common/SimilarTools.tsx | 139 + src/components/common/Skeletons.tsx | 143 + src/components/common/SkillInstallButton.tsx | 232 + src/components/common/StatsSummary.tsx | 111 + src/components/common/ToolLivePreview.tsx | 60 + src/components/community/CheckInRanking.tsx | 104 + src/components/community/HotContent.tsx | 253 + src/components/forum/AchievementList.tsx | 3 +- src/components/forum/ActivityHeatmap.tsx | 359 +- src/components/forum/AvatarPicker.tsx | 277 + src/components/forum/BotAvatar.tsx | 6 +- src/components/forum/CheckInCard.tsx | 236 +- src/components/forum/FeaturedBots.tsx | 6 +- src/components/forum/ForumBoard.tsx | 2 +- src/components/forum/ForumEditor.tsx | 2 +- src/components/forum/ForumTopicCard.tsx | 5 +- src/components/forum/MentionTextarea.tsx | 5 +- src/components/forum/NewTopicDialog.tsx | 10 +- src/components/forum/NewcomerOnboard.tsx | 405 +- src/components/forum/NotificationBell.tsx | 84 +- src/components/forum/PostActionBar.tsx | 119 +- src/components/forum/PostActions.tsx | 1 + src/components/forum/QuickReactions.tsx | 179 + src/components/forum/ReportDialog.tsx | 2 +- src/components/forum/SearchBox.tsx | 444 +- src/components/forum/UserActivityCard.tsx | 108 +- src/components/forum/UserAvatar.tsx | 5 +- src/components/layout/Footer.tsx | 74 +- src/components/layout/Header.tsx | 23 +- src/components/seo/JsonLd.tsx | 189 + src/components/ui/LazyImage.tsx | 53 + src/components/ui/SearchBox.tsx | 44 + src/components/ui/VirtualList.tsx | 49 + src/components/ui/card.tsx | 2 +- src/components/ui/dialog.tsx | 2 +- src/components/ui/skeleton.tsx | 15 + src/components/user/ApiKeyPanel.tsx | 442 ++ src/hooks/useDebounce.ts | 19 + src/lib/__tests__/achievements.test.ts | 503 ++ src/lib/__tests__/api-error.test.ts | 61 + src/lib/__tests__/api-key-auth.test.ts | 42 + src/lib/__tests__/elo.test.ts | 207 + src/lib/__tests__/forum-hot.test.ts | 240 + src/lib/__tests__/level-config.test.ts | 305 + src/lib/__tests__/points-reward.test.ts | 243 + src/lib/__tests__/rate-limit.test.ts | 105 + src/lib/__tests__/reply-quality.test.ts | 64 + src/lib/__tests__/topic-diversity.test.ts | 37 + src/lib/achievements.ts | 410 +- src/lib/admin-auth.ts | 24 +- src/lib/api-error.ts | 33 + src/lib/api-key-auth.ts | 53 + src/lib/auth.ts | 23 +- src/lib/avatar-library.ts | 30 + src/lib/bot-utils.ts | 26 +- src/lib/cache.ts | 84 + src/lib/constants.ts | 11 + src/lib/deepseek.ts | 2 +- src/lib/elo.ts | 355 ++ src/lib/forum-notifications.ts | 139 + src/lib/level-config.ts | 43 + src/lib/performance.ts | 101 + src/lib/points-reward.ts | 49 + src/lib/rate-limit.ts | 19 + src/lib/shop-items.ts | 91 + src/lib/source-type.ts | 19 + src/lib/streak-freeze.ts | 218 + src/lib/utils.ts | 12 + src/lib/validation.ts | 22 + src/middleware.ts | 22 +- tsconfig.json | 1 + vitest.config.ts | 15 + vitest.setup.ts | 1 + 1185 files changed, 49841 insertions(+), 12802 deletions(-) create mode 100644 .trae/ai_coding_knowledge.json create mode 100644 .trae/knowledge_graph.json create mode 100644 .trae/knowledge_graph.jsonl create mode 100644 .trae/rules/README.md create mode 100644 .trae/rules/ai_agent_rules.md create mode 100644 .trae/rules/ai_collaboration.md create mode 100644 .trae/specs/modules/17-rules.md create mode 100644 .trae/specs/modules/notifications.md create mode 100644 .trae/specs/modules/points.md create mode 100644 .trae/specs/modules/search.md create mode 100644 .trae/specs/modules/testing.md create mode 100644 .trae/specs/modules/theme.md create mode 100644 .trae/specs/modules/tools.md delete mode 100644 Temp/check-server.sh create mode 100644 prisma/migrations/20260824170000_add_public_share_and_screenshots/migration.sql create mode 100644 prisma/migrations/20260905180000_add_thinktank/migration.sql create mode 100644 public/avatars/adventurer_001.svg create mode 100644 public/avatars/adventurer_002.svg create mode 100644 public/avatars/adventurer_003.svg create mode 100644 public/avatars/adventurer_004.svg create mode 100644 public/avatars/adventurer_005.svg create mode 100644 public/avatars/adventurer_006.svg create mode 100644 public/avatars/adventurer_007.svg create mode 100644 public/avatars/adventurer_008.svg create mode 100644 public/avatars/adventurer_009.svg create mode 100644 public/avatars/adventurer_010.svg create mode 100644 public/avatars/avataaars_001.svg create mode 100644 public/avatars/avataaars_002.svg create mode 100644 public/avatars/avataaars_003.svg create mode 100644 public/avatars/avataaars_004.svg create mode 100644 public/avatars/avataaars_005.svg create mode 100644 public/avatars/avataaars_006.svg create mode 100644 public/avatars/avataaars_007.svg create mode 100644 public/avatars/avataaars_008.svg create mode 100644 public/avatars/avataaars_009.svg create mode 100644 public/avatars/avataaars_010.svg create mode 100644 public/avatars/big-smile_001.svg create mode 100644 public/avatars/big-smile_002.svg create mode 100644 public/avatars/big-smile_003.svg create mode 100644 public/avatars/big-smile_004.svg create mode 100644 public/avatars/big-smile_005.svg create mode 100644 public/avatars/big-smile_006.svg create mode 100644 public/avatars/big-smile_007.svg create mode 100644 public/avatars/big-smile_008.svg create mode 100644 public/avatars/big-smile_009.svg create mode 100644 public/avatars/big-smile_010.svg create mode 100644 public/avatars/bottts-neutral_001.svg create mode 100644 public/avatars/bottts-neutral_002.svg create mode 100644 public/avatars/bottts-neutral_003.svg create mode 100644 public/avatars/bottts-neutral_004.svg create mode 100644 public/avatars/bottts-neutral_005.svg create mode 100644 public/avatars/bottts-neutral_006.svg create mode 100644 public/avatars/bottts-neutral_007.svg create mode 100644 public/avatars/bottts-neutral_008.svg create mode 100644 public/avatars/bottts-neutral_009.svg create mode 100644 public/avatars/bottts-neutral_010.svg create mode 100644 public/avatars/bottts_001.svg create mode 100644 public/avatars/bottts_002.svg create mode 100644 public/avatars/bottts_003.svg create mode 100644 public/avatars/bottts_004.svg create mode 100644 public/avatars/bottts_005.svg create mode 100644 public/avatars/bottts_006.svg create mode 100644 public/avatars/bottts_007.svg create mode 100644 public/avatars/bottts_008.svg create mode 100644 public/avatars/bottts_009.svg create mode 100644 public/avatars/bottts_010.svg create mode 100644 public/avatars/croodles_001.svg create mode 100644 public/avatars/croodles_002.svg create mode 100644 public/avatars/croodles_003.svg create mode 100644 public/avatars/croodles_004.svg create mode 100644 public/avatars/croodles_005.svg create mode 100644 public/avatars/croodles_006.svg create mode 100644 public/avatars/croodles_007.svg create mode 100644 public/avatars/croodles_008.svg create mode 100644 public/avatars/croodles_009.svg create mode 100644 public/avatars/croodles_010.svg create mode 100644 public/avatars/female_business_000.svg create mode 100644 public/avatars/female_business_001.svg create mode 100644 public/avatars/female_business_002.svg create mode 100644 public/avatars/female_business_003.svg create mode 100644 public/avatars/female_business_004.svg create mode 100644 public/avatars/female_business_005.svg create mode 100644 public/avatars/female_business_006.svg create mode 100644 public/avatars/female_business_007.svg create mode 100644 public/avatars/female_business_008.svg create mode 100644 public/avatars/female_business_009.svg create mode 100644 public/avatars/female_business_010.svg create mode 100644 public/avatars/female_business_011.svg create mode 100644 public/avatars/female_business_012.svg create mode 100644 public/avatars/female_business_013.svg create mode 100644 public/avatars/female_business_014.svg create mode 100644 public/avatars/female_business_015.svg create mode 100644 public/avatars/female_business_016.svg create mode 100644 public/avatars/female_business_017.svg create mode 100644 public/avatars/female_business_018.svg create mode 100644 public/avatars/female_business_019.svg create mode 100644 public/avatars/female_creative_000.svg create mode 100644 public/avatars/female_creative_001.svg create mode 100644 public/avatars/female_creative_002.svg create mode 100644 public/avatars/female_creative_003.svg create mode 100644 public/avatars/female_creative_004.svg create mode 100644 public/avatars/female_creative_005.svg create mode 100644 public/avatars/female_creative_006.svg create mode 100644 public/avatars/female_creative_007.svg create mode 100644 public/avatars/female_creative_008.svg create mode 100644 public/avatars/female_creative_009.svg create mode 100644 public/avatars/female_creative_010.svg create mode 100644 public/avatars/female_creative_011.svg create mode 100644 public/avatars/female_creative_012.svg create mode 100644 public/avatars/female_creative_013.svg create mode 100644 public/avatars/female_creative_014.svg create mode 100644 public/avatars/female_creative_015.svg create mode 100644 public/avatars/female_creative_016.svg create mode 100644 public/avatars/female_creative_017.svg create mode 100644 public/avatars/female_creative_018.svg create mode 100644 public/avatars/female_creative_019.svg create mode 100644 public/avatars/female_creative_020.svg create mode 100644 public/avatars/female_creative_021.svg create mode 100644 public/avatars/female_creative_022.svg create mode 100644 public/avatars/female_creative_023.svg create mode 100644 public/avatars/female_creative_024.svg create mode 100644 public/avatars/female_creative_025.svg create mode 100644 public/avatars/female_creative_026.svg create mode 100644 public/avatars/female_creative_027.svg create mode 100644 public/avatars/female_creative_028.svg create mode 100644 public/avatars/female_creative_029.svg create mode 100644 public/avatars/female_cute_000.svg create mode 100644 public/avatars/female_cute_001.svg create mode 100644 public/avatars/female_cute_002.svg create mode 100644 public/avatars/female_cute_003.svg create mode 100644 public/avatars/female_cute_004.svg create mode 100644 public/avatars/female_cute_005.svg create mode 100644 public/avatars/female_cute_006.svg create mode 100644 public/avatars/female_cute_007.svg create mode 100644 public/avatars/female_cute_008.svg create mode 100644 public/avatars/female_cute_009.svg create mode 100644 public/avatars/female_cute_010.svg create mode 100644 public/avatars/female_cute_011.svg create mode 100644 public/avatars/female_cute_012.svg create mode 100644 public/avatars/female_cute_013.svg create mode 100644 public/avatars/female_cute_014.svg create mode 100644 public/avatars/female_cute_015.svg create mode 100644 public/avatars/female_cute_016.svg create mode 100644 public/avatars/female_cute_017.svg create mode 100644 public/avatars/female_cute_018.svg create mode 100644 public/avatars/female_cute_019.svg create mode 100644 public/avatars/female_cute_020.svg create mode 100644 public/avatars/female_cute_021.svg create mode 100644 public/avatars/female_cute_022.svg create mode 100644 public/avatars/female_cute_023.svg create mode 100644 public/avatars/female_cute_024.svg create mode 100644 public/avatars/female_nature_000.svg create mode 100644 public/avatars/female_nature_001.svg create mode 100644 public/avatars/female_nature_002.svg create mode 100644 public/avatars/female_nature_003.svg create mode 100644 public/avatars/female_nature_004.svg create mode 100644 public/avatars/female_nature_005.svg create mode 100644 public/avatars/female_nature_006.svg create mode 100644 public/avatars/female_nature_007.svg create mode 100644 public/avatars/female_nature_008.svg create mode 100644 public/avatars/female_nature_009.svg create mode 100644 public/avatars/female_nature_010.svg create mode 100644 public/avatars/female_nature_011.svg create mode 100644 public/avatars/female_nature_012.svg create mode 100644 public/avatars/female_nature_013.svg create mode 100644 public/avatars/female_nature_014.svg create mode 100644 public/avatars/female_sport_000.svg create mode 100644 public/avatars/female_sport_001.svg create mode 100644 public/avatars/female_sport_002.svg create mode 100644 public/avatars/female_sport_003.svg create mode 100644 public/avatars/female_sport_004.svg create mode 100644 public/avatars/female_sport_005.svg create mode 100644 public/avatars/female_sport_006.svg create mode 100644 public/avatars/female_sport_007.svg create mode 100644 public/avatars/female_sport_008.svg create mode 100644 public/avatars/female_sport_009.svg create mode 100644 public/avatars/female_sport_010.svg create mode 100644 public/avatars/female_sport_011.svg create mode 100644 public/avatars/female_sport_012.svg create mode 100644 public/avatars/female_sport_013.svg create mode 100644 public/avatars/female_sport_014.svg create mode 100644 public/avatars/female_tech_000.svg create mode 100644 public/avatars/female_tech_001.svg create mode 100644 public/avatars/female_tech_002.svg create mode 100644 public/avatars/female_tech_003.svg create mode 100644 public/avatars/female_tech_004.svg create mode 100644 public/avatars/female_tech_005.svg create mode 100644 public/avatars/female_tech_006.svg create mode 100644 public/avatars/female_tech_007.svg create mode 100644 public/avatars/female_tech_008.svg create mode 100644 public/avatars/female_tech_009.svg create mode 100644 public/avatars/female_tech_010.svg create mode 100644 public/avatars/female_tech_011.svg create mode 100644 public/avatars/female_tech_012.svg create mode 100644 public/avatars/female_tech_013.svg create mode 100644 public/avatars/female_tech_014.svg create mode 100644 public/avatars/female_tech_015.svg create mode 100644 public/avatars/female_tech_016.svg create mode 100644 public/avatars/female_tech_017.svg create mode 100644 public/avatars/female_tech_018.svg create mode 100644 public/avatars/female_tech_019.svg create mode 100644 public/avatars/fun-emoji_001.svg create mode 100644 public/avatars/fun-emoji_002.svg create mode 100644 public/avatars/fun-emoji_003.svg create mode 100644 public/avatars/fun-emoji_004.svg create mode 100644 public/avatars/fun-emoji_005.svg create mode 100644 public/avatars/fun-emoji_006.svg create mode 100644 public/avatars/fun-emoji_007.svg create mode 100644 public/avatars/fun-emoji_008.svg create mode 100644 public/avatars/fun-emoji_009.svg create mode 100644 public/avatars/fun-emoji_010.svg create mode 100644 public/avatars/lorelei_001.svg create mode 100644 public/avatars/lorelei_002.svg create mode 100644 public/avatars/lorelei_003.svg create mode 100644 public/avatars/lorelei_004.svg create mode 100644 public/avatars/lorelei_005.svg create mode 100644 public/avatars/lorelei_006.svg create mode 100644 public/avatars/lorelei_007.svg create mode 100644 public/avatars/lorelei_008.svg create mode 100644 public/avatars/lorelei_009.svg create mode 100644 public/avatars/lorelei_010.svg create mode 100644 public/avatars/male_business_000.svg create mode 100644 public/avatars/male_business_001.svg create mode 100644 public/avatars/male_business_002.svg create mode 100644 public/avatars/male_business_003.svg create mode 100644 public/avatars/male_business_004.svg create mode 100644 public/avatars/male_business_005.svg create mode 100644 public/avatars/male_business_006.svg create mode 100644 public/avatars/male_business_007.svg create mode 100644 public/avatars/male_business_008.svg create mode 100644 public/avatars/male_business_009.svg create mode 100644 public/avatars/male_business_010.svg create mode 100644 public/avatars/male_business_011.svg create mode 100644 public/avatars/male_business_012.svg create mode 100644 public/avatars/male_business_013.svg create mode 100644 public/avatars/male_business_014.svg create mode 100644 public/avatars/male_business_015.svg create mode 100644 public/avatars/male_business_016.svg create mode 100644 public/avatars/male_business_017.svg create mode 100644 public/avatars/male_business_018.svg create mode 100644 public/avatars/male_business_019.svg create mode 100644 public/avatars/male_business_020.svg create mode 100644 public/avatars/male_business_021.svg create mode 100644 public/avatars/male_business_022.svg create mode 100644 public/avatars/male_business_023.svg create mode 100644 public/avatars/male_business_024.svg create mode 100644 public/avatars/male_business_025.svg create mode 100644 public/avatars/male_business_026.svg create mode 100644 public/avatars/male_business_027.svg create mode 100644 public/avatars/male_business_028.svg create mode 100644 public/avatars/male_business_029.svg create mode 100644 public/avatars/male_business_030.svg create mode 100644 public/avatars/male_business_031.svg create mode 100644 public/avatars/male_business_032.svg create mode 100644 public/avatars/male_business_033.svg create mode 100644 public/avatars/male_business_034.svg create mode 100644 public/avatars/male_casual_000.svg create mode 100644 public/avatars/male_casual_001.svg create mode 100644 public/avatars/male_casual_002.svg create mode 100644 public/avatars/male_casual_003.svg create mode 100644 public/avatars/male_casual_004.svg create mode 100644 public/avatars/male_casual_005.svg create mode 100644 public/avatars/male_casual_006.svg create mode 100644 public/avatars/male_casual_007.svg create mode 100644 public/avatars/male_casual_008.svg create mode 100644 public/avatars/male_casual_009.svg create mode 100644 public/avatars/male_casual_010.svg create mode 100644 public/avatars/male_casual_011.svg create mode 100644 public/avatars/male_casual_012.svg create mode 100644 public/avatars/male_casual_013.svg create mode 100644 public/avatars/male_casual_014.svg create mode 100644 public/avatars/male_creative_000.svg create mode 100644 public/avatars/male_creative_001.svg create mode 100644 public/avatars/male_creative_002.svg create mode 100644 public/avatars/male_creative_003.svg create mode 100644 public/avatars/male_creative_004.svg create mode 100644 public/avatars/male_creative_005.svg create mode 100644 public/avatars/male_creative_006.svg create mode 100644 public/avatars/male_creative_007.svg create mode 100644 public/avatars/male_creative_008.svg create mode 100644 public/avatars/male_creative_009.svg create mode 100644 public/avatars/male_creative_010.svg create mode 100644 public/avatars/male_creative_011.svg create mode 100644 public/avatars/male_creative_012.svg create mode 100644 public/avatars/male_creative_013.svg create mode 100644 public/avatars/male_creative_014.svg create mode 100644 public/avatars/male_creative_015.svg create mode 100644 public/avatars/male_creative_016.svg create mode 100644 public/avatars/male_creative_017.svg create mode 100644 public/avatars/male_creative_018.svg create mode 100644 public/avatars/male_creative_019.svg create mode 100644 public/avatars/male_dark_000.svg create mode 100644 public/avatars/male_dark_001.svg create mode 100644 public/avatars/male_dark_002.svg create mode 100644 public/avatars/male_dark_003.svg create mode 100644 public/avatars/male_dark_004.svg create mode 100644 public/avatars/male_dark_005.svg create mode 100644 public/avatars/male_dark_006.svg create mode 100644 public/avatars/male_dark_007.svg create mode 100644 public/avatars/male_dark_008.svg create mode 100644 public/avatars/male_dark_009.svg create mode 100644 public/avatars/male_sport_000.svg create mode 100644 public/avatars/male_sport_001.svg create mode 100644 public/avatars/male_sport_002.svg create mode 100644 public/avatars/male_sport_003.svg create mode 100644 public/avatars/male_sport_004.svg create mode 100644 public/avatars/male_sport_005.svg create mode 100644 public/avatars/male_sport_006.svg create mode 100644 public/avatars/male_sport_007.svg create mode 100644 public/avatars/male_sport_008.svg create mode 100644 public/avatars/male_sport_009.svg create mode 100644 public/avatars/male_sport_010.svg create mode 100644 public/avatars/male_sport_011.svg create mode 100644 public/avatars/male_sport_012.svg create mode 100644 public/avatars/male_sport_013.svg create mode 100644 public/avatars/male_sport_014.svg create mode 100644 public/avatars/male_sport_015.svg create mode 100644 public/avatars/male_sport_016.svg create mode 100644 public/avatars/male_sport_017.svg create mode 100644 public/avatars/male_sport_018.svg create mode 100644 public/avatars/male_sport_019.svg create mode 100644 public/avatars/male_tech_000.svg create mode 100644 public/avatars/male_tech_001.svg create mode 100644 public/avatars/male_tech_002.svg create mode 100644 public/avatars/male_tech_003.svg create mode 100644 public/avatars/male_tech_004.svg create mode 100644 public/avatars/male_tech_005.svg create mode 100644 public/avatars/male_tech_006.svg create mode 100644 public/avatars/male_tech_007.svg create mode 100644 public/avatars/male_tech_008.svg create mode 100644 public/avatars/male_tech_009.svg create mode 100644 public/avatars/male_tech_010.svg create mode 100644 public/avatars/male_tech_011.svg create mode 100644 public/avatars/male_tech_012.svg create mode 100644 public/avatars/male_tech_013.svg create mode 100644 public/avatars/male_tech_014.svg create mode 100644 public/avatars/male_tech_015.svg create mode 100644 public/avatars/male_tech_016.svg create mode 100644 public/avatars/male_tech_017.svg create mode 100644 public/avatars/male_tech_018.svg create mode 100644 public/avatars/male_tech_019.svg create mode 100644 public/avatars/male_tech_020.svg create mode 100644 public/avatars/male_tech_021.svg create mode 100644 public/avatars/male_tech_022.svg create mode 100644 public/avatars/male_tech_023.svg create mode 100644 public/avatars/male_tech_024.svg create mode 100644 public/avatars/manifest.json create mode 100644 public/avatars/micah_001.svg create mode 100644 public/avatars/micah_002.svg create mode 100644 public/avatars/micah_003.svg create mode 100644 public/avatars/micah_004.svg create mode 100644 public/avatars/micah_005.svg create mode 100644 public/avatars/micah_006.svg create mode 100644 public/avatars/micah_007.svg create mode 100644 public/avatars/micah_008.svg create mode 100644 public/avatars/micah_009.svg create mode 100644 public/avatars/micah_010.svg create mode 100644 public/avatars/neutral_abstract_000.svg create mode 100644 public/avatars/neutral_abstract_001.svg create mode 100644 public/avatars/neutral_abstract_002.svg create mode 100644 public/avatars/neutral_abstract_003.svg create mode 100644 public/avatars/neutral_abstract_004.svg create mode 100644 public/avatars/neutral_abstract_005.svg create mode 100644 public/avatars/neutral_abstract_006.svg create mode 100644 public/avatars/neutral_abstract_007.svg create mode 100644 public/avatars/neutral_abstract_008.svg create mode 100644 public/avatars/neutral_abstract_009.svg create mode 100644 public/avatars/neutral_abstract_010.svg create mode 100644 public/avatars/neutral_abstract_011.svg create mode 100644 public/avatars/neutral_abstract_012.svg create mode 100644 public/avatars/neutral_abstract_013.svg create mode 100644 public/avatars/neutral_abstract_014.svg create mode 100644 public/avatars/neutral_abstract_015.svg create mode 100644 public/avatars/neutral_abstract_016.svg create mode 100644 public/avatars/neutral_abstract_017.svg create mode 100644 public/avatars/neutral_abstract_018.svg create mode 100644 public/avatars/neutral_abstract_019.svg create mode 100644 public/avatars/neutral_abstract_020.svg create mode 100644 public/avatars/neutral_abstract_021.svg create mode 100644 public/avatars/neutral_abstract_022.svg create mode 100644 public/avatars/neutral_abstract_023.svg create mode 100644 public/avatars/neutral_abstract_024.svg create mode 100644 public/avatars/neutral_abstract_025.svg create mode 100644 public/avatars/neutral_abstract_026.svg create mode 100644 public/avatars/neutral_abstract_027.svg create mode 100644 public/avatars/neutral_abstract_028.svg create mode 100644 public/avatars/neutral_abstract_029.svg create mode 100644 public/avatars/neutral_cute_000.svg create mode 100644 public/avatars/neutral_cute_001.svg create mode 100644 public/avatars/neutral_cute_002.svg create mode 100644 public/avatars/neutral_cute_003.svg create mode 100644 public/avatars/neutral_cute_004.svg create mode 100644 public/avatars/neutral_cute_005.svg create mode 100644 public/avatars/neutral_cute_006.svg create mode 100644 public/avatars/neutral_cute_007.svg create mode 100644 public/avatars/neutral_cute_008.svg create mode 100644 public/avatars/neutral_cute_009.svg create mode 100644 public/avatars/neutral_cute_010.svg create mode 100644 public/avatars/neutral_cute_011.svg create mode 100644 public/avatars/neutral_cute_012.svg create mode 100644 public/avatars/neutral_cute_013.svg create mode 100644 public/avatars/neutral_cute_014.svg create mode 100644 public/avatars/neutral_cute_015.svg create mode 100644 public/avatars/neutral_cute_016.svg create mode 100644 public/avatars/neutral_cute_017.svg create mode 100644 public/avatars/neutral_cute_018.svg create mode 100644 public/avatars/neutral_cute_019.svg create mode 100644 public/avatars/neutral_geometric_000.svg create mode 100644 public/avatars/neutral_geometric_001.svg create mode 100644 public/avatars/neutral_geometric_002.svg create mode 100644 public/avatars/neutral_geometric_003.svg create mode 100644 public/avatars/neutral_geometric_004.svg create mode 100644 public/avatars/neutral_geometric_005.svg create mode 100644 public/avatars/neutral_geometric_006.svg create mode 100644 public/avatars/neutral_geometric_007.svg create mode 100644 public/avatars/neutral_geometric_008.svg create mode 100644 public/avatars/neutral_geometric_009.svg create mode 100644 public/avatars/neutral_geometric_010.svg create mode 100644 public/avatars/neutral_geometric_011.svg create mode 100644 public/avatars/neutral_geometric_012.svg create mode 100644 public/avatars/neutral_geometric_013.svg create mode 100644 public/avatars/neutral_geometric_014.svg create mode 100644 public/avatars/neutral_geometric_015.svg create mode 100644 public/avatars/neutral_geometric_016.svg create mode 100644 public/avatars/neutral_geometric_017.svg create mode 100644 public/avatars/neutral_geometric_018.svg create mode 100644 public/avatars/neutral_geometric_019.svg create mode 100644 public/avatars/neutral_minimal_000.svg create mode 100644 public/avatars/neutral_minimal_001.svg create mode 100644 public/avatars/neutral_minimal_002.svg create mode 100644 public/avatars/neutral_minimal_003.svg create mode 100644 public/avatars/neutral_minimal_004.svg create mode 100644 public/avatars/neutral_minimal_005.svg create mode 100644 public/avatars/neutral_minimal_006.svg create mode 100644 public/avatars/neutral_minimal_007.svg create mode 100644 public/avatars/neutral_minimal_008.svg create mode 100644 public/avatars/neutral_minimal_009.svg create mode 100644 public/avatars/neutral_minimal_010.svg create mode 100644 public/avatars/neutral_minimal_011.svg create mode 100644 public/avatars/neutral_minimal_012.svg create mode 100644 public/avatars/neutral_minimal_013.svg create mode 100644 public/avatars/neutral_minimal_014.svg create mode 100644 public/avatars/neutral_minimal_015.svg create mode 100644 public/avatars/neutral_minimal_016.svg create mode 100644 public/avatars/neutral_minimal_017.svg create mode 100644 public/avatars/neutral_minimal_018.svg create mode 100644 public/avatars/neutral_minimal_019.svg create mode 100644 public/avatars/neutral_minimal_020.svg create mode 100644 public/avatars/neutral_minimal_021.svg create mode 100644 public/avatars/neutral_minimal_022.svg create mode 100644 public/avatars/neutral_minimal_023.svg create mode 100644 public/avatars/neutral_minimal_024.svg create mode 100644 public/avatars/neutral_nature_000.svg create mode 100644 public/avatars/neutral_nature_001.svg create mode 100644 public/avatars/neutral_nature_002.svg create mode 100644 public/avatars/neutral_nature_003.svg create mode 100644 public/avatars/neutral_nature_004.svg create mode 100644 public/avatars/neutral_nature_005.svg create mode 100644 public/avatars/neutral_nature_006.svg create mode 100644 public/avatars/neutral_nature_007.svg create mode 100644 public/avatars/neutral_nature_008.svg create mode 100644 public/avatars/neutral_nature_009.svg create mode 100644 public/avatars/neutral_nature_010.svg create mode 100644 public/avatars/neutral_nature_011.svg create mode 100644 public/avatars/neutral_nature_012.svg create mode 100644 public/avatars/neutral_nature_013.svg create mode 100644 public/avatars/neutral_nature_014.svg create mode 100644 public/avatars/neutral_nature_015.svg create mode 100644 public/avatars/neutral_nature_016.svg create mode 100644 public/avatars/neutral_nature_017.svg create mode 100644 public/avatars/neutral_nature_018.svg create mode 100644 public/avatars/neutral_nature_019.svg create mode 100644 public/avatars/neutral_nature_020.svg create mode 100644 public/avatars/neutral_nature_021.svg create mode 100644 public/avatars/neutral_nature_022.svg create mode 100644 public/avatars/neutral_nature_023.svg create mode 100644 public/avatars/neutral_nature_024.svg create mode 100644 public/avatars/neutral_retro_000.svg create mode 100644 public/avatars/neutral_retro_001.svg create mode 100644 public/avatars/neutral_retro_002.svg create mode 100644 public/avatars/neutral_retro_003.svg create mode 100644 public/avatars/neutral_retro_004.svg create mode 100644 public/avatars/neutral_retro_005.svg create mode 100644 public/avatars/neutral_retro_006.svg create mode 100644 public/avatars/neutral_retro_007.svg create mode 100644 public/avatars/neutral_retro_008.svg create mode 100644 public/avatars/neutral_retro_009.svg create mode 100644 public/avatars/neutral_retro_010.svg create mode 100644 public/avatars/neutral_retro_011.svg create mode 100644 public/avatars/neutral_retro_012.svg create mode 100644 public/avatars/neutral_retro_013.svg create mode 100644 public/avatars/neutral_retro_014.svg create mode 100644 public/avatars/neutral_retro_015.svg create mode 100644 public/avatars/neutral_retro_016.svg create mode 100644 public/avatars/neutral_retro_017.svg create mode 100644 public/avatars/neutral_retro_018.svg create mode 100644 public/avatars/neutral_retro_019.svg create mode 100644 public/avatars/neutral_space_000.svg create mode 100644 public/avatars/neutral_space_001.svg create mode 100644 public/avatars/neutral_space_002.svg create mode 100644 public/avatars/neutral_space_003.svg create mode 100644 public/avatars/neutral_space_004.svg create mode 100644 public/avatars/neutral_space_005.svg create mode 100644 public/avatars/neutral_space_006.svg create mode 100644 public/avatars/neutral_space_007.svg create mode 100644 public/avatars/neutral_space_008.svg create mode 100644 public/avatars/neutral_space_009.svg create mode 100644 public/avatars/neutral_space_010.svg create mode 100644 public/avatars/neutral_space_011.svg create mode 100644 public/avatars/neutral_space_012.svg create mode 100644 public/avatars/neutral_space_013.svg create mode 100644 public/avatars/neutral_space_014.svg create mode 100644 public/avatars/neutral_space_015.svg create mode 100644 public/avatars/neutral_space_016.svg create mode 100644 public/avatars/neutral_space_017.svg create mode 100644 public/avatars/neutral_space_018.svg create mode 100644 public/avatars/neutral_space_019.svg create mode 100644 public/avatars/notionists_001.svg create mode 100644 public/avatars/notionists_002.svg create mode 100644 public/avatars/notionists_003.svg create mode 100644 public/avatars/notionists_004.svg create mode 100644 public/avatars/notionists_005.svg create mode 100644 public/avatars/notionists_006.svg create mode 100644 public/avatars/notionists_007.svg create mode 100644 public/avatars/notionists_008.svg create mode 100644 public/avatars/notionists_009.svg create mode 100644 public/avatars/notionists_010.svg create mode 100644 public/avatars/open-peeps_001.svg create mode 100644 public/avatars/open-peeps_002.svg create mode 100644 public/avatars/open-peeps_003.svg create mode 100644 public/avatars/open-peeps_004.svg create mode 100644 public/avatars/open-peeps_005.svg create mode 100644 public/avatars/open-peeps_006.svg create mode 100644 public/avatars/open-peeps_007.svg create mode 100644 public/avatars/open-peeps_008.svg create mode 100644 public/avatars/open-peeps_009.svg create mode 100644 public/avatars/open-peeps_010.svg create mode 100644 public/avatars/pixel-art_001.svg create mode 100644 public/avatars/pixel-art_002.svg create mode 100644 public/avatars/pixel-art_003.svg create mode 100644 public/avatars/pixel-art_004.svg create mode 100644 public/avatars/pixel-art_005.svg create mode 100644 public/avatars/pixel-art_006.svg create mode 100644 public/avatars/pixel-art_007.svg create mode 100644 public/avatars/pixel-art_008.svg create mode 100644 public/avatars/pixel-art_009.svg create mode 100644 public/avatars/pixel-art_010.svg create mode 100644 public/bot-avatars/passerby_ai-tech_comparer_62.svg create mode 100644 public/bot-avatars/passerby_ai-tech_enthusiast_32.svg create mode 100644 public/bot-avatars/passerby_ai-tech_learner_52.svg create mode 100644 public/bot-avatars/passerby_ai-tech_newbie_2.svg create mode 100644 public/bot-avatars/passerby_ai-tech_observer_12.svg create mode 100644 public/bot-avatars/passerby_ai-tech_questioner_22.svg create mode 100644 public/bot-avatars/passerby_ai-tech_skeptic_42.svg create mode 100644 public/bot-avatars/passerby_career_comparer_63.svg create mode 100644 public/bot-avatars/passerby_career_enthusiast_33.svg create mode 100644 public/bot-avatars/passerby_career_learner_53.svg create mode 100644 public/bot-avatars/passerby_career_newbie_3.svg create mode 100644 public/bot-avatars/passerby_career_observer_13.svg create mode 100644 public/bot-avatars/passerby_career_questioner_23.svg create mode 100644 public/bot-avatars/passerby_career_skeptic_43.svg create mode 100644 public/bot-avatars/passerby_content_enthusiast_36.svg create mode 100644 public/bot-avatars/passerby_content_learner_56.svg create mode 100644 public/bot-avatars/passerby_content_newbie_6.svg create mode 100644 public/bot-avatars/passerby_content_observer_16.svg create mode 100644 public/bot-avatars/passerby_content_questioner_26.svg create mode 100644 public/bot-avatars/passerby_content_skeptic_46.svg create mode 100644 public/bot-avatars/passerby_cross-border_comparer_64.svg create mode 100644 public/bot-avatars/passerby_cross-border_enthusiast_34.svg create mode 100644 public/bot-avatars/passerby_cross-border_learner_54.svg create mode 100644 public/bot-avatars/passerby_cross-border_newbie_4.svg create mode 100644 public/bot-avatars/passerby_cross-border_observer_14.svg create mode 100644 public/bot-avatars/passerby_cross-border_questioner_24.svg create mode 100644 public/bot-avatars/passerby_cross-border_skeptic_44.svg create mode 100644 public/bot-avatars/passerby_ecommerce_comparer_61.svg create mode 100644 public/bot-avatars/passerby_ecommerce_enthusiast_31.svg create mode 100644 public/bot-avatars/passerby_ecommerce_learner_51.svg create mode 100644 public/bot-avatars/passerby_ecommerce_newbie_1.svg create mode 100644 public/bot-avatars/passerby_ecommerce_observer_11.svg create mode 100644 public/bot-avatars/passerby_ecommerce_questioner_21.svg create mode 100644 public/bot-avatars/passerby_ecommerce_skeptic_41.svg create mode 100644 public/bot-avatars/passerby_education_enthusiast_38.svg create mode 100644 public/bot-avatars/passerby_education_learner_58.svg create mode 100644 public/bot-avatars/passerby_education_newbie_8.svg create mode 100644 public/bot-avatars/passerby_education_observer_18.svg create mode 100644 public/bot-avatars/passerby_education_questioner_28.svg create mode 100644 public/bot-avatars/passerby_education_skeptic_48.svg create mode 100644 public/bot-avatars/passerby_fire-life_enthusiast_39.svg create mode 100644 public/bot-avatars/passerby_fire-life_learner_59.svg create mode 100644 public/bot-avatars/passerby_fire-life_newbie_9.svg create mode 100644 public/bot-avatars/passerby_fire-life_observer_19.svg create mode 100644 public/bot-avatars/passerby_fire-life_questioner_29.svg create mode 100644 public/bot-avatars/passerby_fire-life_skeptic_49.svg create mode 100644 public/bot-avatars/passerby_money_comparer_60.svg create mode 100644 public/bot-avatars/passerby_money_enthusiast_30.svg create mode 100644 public/bot-avatars/passerby_money_learner_50.svg create mode 100644 public/bot-avatars/passerby_money_newbie_0.svg create mode 100644 public/bot-avatars/passerby_money_observer_10.svg create mode 100644 public/bot-avatars/passerby_money_questioner_20.svg create mode 100644 public/bot-avatars/passerby_money_skeptic_40.svg create mode 100644 public/bot-avatars/passerby_offline-biz_enthusiast_37.svg create mode 100644 public/bot-avatars/passerby_offline-biz_learner_57.svg create mode 100644 public/bot-avatars/passerby_offline-biz_newbie_7.svg create mode 100644 public/bot-avatars/passerby_offline-biz_observer_17.svg create mode 100644 public/bot-avatars/passerby_offline-biz_questioner_27.svg create mode 100644 public/bot-avatars/passerby_offline-biz_skeptic_47.svg create mode 100644 public/bot-avatars/passerby_real-estate_comparer_65.svg create mode 100644 public/bot-avatars/passerby_real-estate_enthusiast_35.svg create mode 100644 public/bot-avatars/passerby_real-estate_learner_55.svg create mode 100644 public/bot-avatars/passerby_real-estate_newbie_5.svg create mode 100644 public/bot-avatars/passerby_real-estate_observer_15.svg create mode 100644 public/bot-avatars/passerby_real-estate_questioner_25.svg create mode 100644 public/bot-avatars/passerby_real-estate_skeptic_45.svg create mode 100644 public/manifest.json create mode 100644 public/sw.js create mode 100644 scripts/_forum-clear.cjs delete mode 100644 scripts/_inspection.sh create mode 100644 scripts/_rebuild-avatars.mjs create mode 100644 scripts/bot-roundtable.mjs delete mode 100644 scripts/check-api.mjs delete mode 100644 scripts/check-categories.cjs delete mode 100644 scripts/check-community.py delete mode 100644 scripts/check-coverage.mjs delete mode 100644 scripts/check-forum.mjs delete mode 100644 scripts/check-html-detail.py delete mode 100644 scripts/check-html.py delete mode 100644 scripts/check-industry.mjs delete mode 100644 scripts/check-memories.mjs delete mode 100644 scripts/check-parents.mjs delete mode 100644 scripts/check-render.py delete mode 100644 scripts/check-slugs.py delete mode 100644 scripts/cleanup-non-ai.mjs delete mode 100644 scripts/cleanup-old-forums.mjs create mode 100644 scripts/competitor-monitor.mjs delete mode 100644 scripts/cron-daily-discover.sh delete mode 100644 scripts/cron-daily-news.sh delete mode 100644 scripts/cron-task1.sh delete mode 100644 scripts/cron-wrapper.sh delete mode 100644 scripts/debug-html.py delete mode 100644 scripts/debug-json.mjs delete mode 100644 scripts/debug-rsc.py delete mode 100644 scripts/debug-section.py delete mode 100644 scripts/delete-drafts.mjs create mode 100644 scripts/deploy-build.sh create mode 100644 scripts/deploy-cron.sh create mode 100644 scripts/deploy-run.sh create mode 100644 scripts/enrich-tool-data.mjs delete mode 100644 scripts/final-check.py delete mode 100644 scripts/find-chunks.py delete mode 100644 scripts/find-section.py delete mode 100644 scripts/fix-db-url.cjs delete mode 100644 scripts/fix-db-url.sh delete mode 100644 scripts/fix-ts-types.cjs create mode 100644 scripts/generate-avatar-library.mjs create mode 100644 scripts/generate-diverse-avatars.mjs create mode 100644 scripts/generate-passerby-roles.mjs create mode 100644 scripts/grant-freeze-cards.mjs create mode 100644 scripts/industry-daily.mjs create mode 100644 scripts/industry-thinktank.mjs delete mode 100644 scripts/install-cron.sh create mode 100644 scripts/lib/chinese-text.mjs create mode 100644 scripts/lib/logger.mjs create mode 100644 scripts/lib/reply-quality.mjs create mode 100644 scripts/lib/task-runner.mjs create mode 100644 scripts/lib/topic-diversity.mjs create mode 100644 scripts/newsletter-generate.mjs create mode 100644 scripts/notification-digest.mjs delete mode 100644 scripts/parse-rsc.py delete mode 100644 scripts/parse-rsc2.py create mode 100644 scripts/prompts/bot-activity.txt create mode 100644 scripts/prompts/bot-feedback.txt create mode 100644 scripts/prompts/bot-roundtable.txt delete mode 100644 scripts/render-test.py delete mode 100644 scripts/test-bot-stats.mjs delete mode 100644 scripts/test-github.mjs delete mode 100644 scripts/test-html.sh delete mode 100644 scripts/test_login.py delete mode 100644 scripts/test_login2.py delete mode 100644 scripts/test_login3.py delete mode 100644 scripts/test_login4.py delete mode 100644 scripts/test_login5.py create mode 100644 scripts/trend-alert.mjs create mode 100644 scripts/update-knowledge.mjs create mode 100644 scripts/verify-deploy-docker.sh delete mode 100644 scripts/verify-deploy.sh delete mode 100644 scripts/verify-fix.py create mode 100644 scripts/weekly-recommend-email.mjs create mode 100644 src/app/(admin)/admin/bot-quality/BotQualityClient.tsx create mode 100644 src/app/(admin)/admin/bot-quality/page.tsx create mode 100644 src/app/(admin)/admin/page.tsx create mode 100644 src/app/(developers)/developers/error.tsx create mode 100644 src/app/(developers)/developers/page.tsx create mode 100644 src/app/(developers)/layout.tsx create mode 100644 src/app/api/admin/bot-quality/route.ts create mode 100644 src/app/api/admin/overview/route.ts create mode 100644 src/app/api/admin/tools/verify/route.ts create mode 100644 src/app/api/community/checkin-leaderboard/route.ts create mode 100644 src/app/api/community/hot/route.ts create mode 100644 src/app/api/community/leaderboard/route.ts create mode 100644 src/app/api/feedback/route.ts create mode 100644 src/app/api/forum/posts/[postId]/tip/route.ts create mode 100644 src/app/api/forum/topics/[id]/react/route.ts create mode 100644 src/app/api/metrics/route.ts create mode 100644 src/app/api/newsletter/latest/route.ts create mode 100644 src/app/api/rss/route.ts create mode 100644 src/app/api/search/suggest/route.ts create mode 100644 src/app/api/shop/items/route.ts create mode 100644 src/app/api/shop/my-items/route.ts create mode 100644 src/app/api/shop/purchase/route.ts create mode 100644 src/app/api/skills/elo-battle/route.ts create mode 100644 src/app/api/skills/elo-categories/route.ts create mode 100644 src/app/api/skills/elo-rankings/route.ts create mode 100644 src/app/api/skills/similar/route.ts create mode 100644 src/app/api/stats/route.ts create mode 100644 src/app/api/tools/similar/route.ts create mode 100644 src/app/api/tools/verified/route.ts create mode 100644 src/app/api/user/achievements/route.ts create mode 100644 src/app/api/user/api-keys/[id]/route.ts create mode 100644 src/app/api/user/api-keys/route.ts create mode 100644 src/app/api/user/avatar/upload/route.ts create mode 100644 src/app/api/user/avatars/route.ts create mode 100644 src/app/api/user/check-in/route.ts create mode 100644 src/app/api/user/notification-prefs/route.ts create mode 100644 src/app/api/user/onboarding/progress/route.ts create mode 100644 src/app/api/user/streak-freeze/route.ts create mode 100644 src/app/api/user/streak-freeze/use/route.ts create mode 100644 src/app/api/v1/collections/[publicSlug]/route.ts create mode 100644 src/app/api/v1/collections/route.ts create mode 100644 src/app/api/v1/search/route.ts create mode 100644 src/app/api/v1/skills/[slug]/route.ts create mode 100644 src/app/api/v1/skills/route.ts create mode 100644 src/app/api/v1/tools/[slug]/route.ts create mode 100644 src/app/api/v1/tools/route.ts create mode 100644 src/app/collections/[publicSlug]/error.tsx create mode 100644 src/app/collections/[publicSlug]/loading.tsx create mode 100644 src/app/collections/[publicSlug]/page.tsx create mode 100644 src/app/collections/error.tsx create mode 100644 src/app/collections/loading.tsx create mode 100644 src/app/collections/page.tsx create mode 100644 src/app/community/error.tsx create mode 100644 src/app/community/loading.tsx create mode 100644 src/app/daily/DailyContent.tsx create mode 100644 src/app/daily/error.tsx create mode 100644 src/app/daily/loading.tsx create mode 100644 src/app/global-error.tsx create mode 100644 src/app/login/error.tsx create mode 100644 src/app/login/loading.tsx create mode 100644 src/app/newsletter/error.tsx create mode 100644 src/app/newsletter/loading.tsx create mode 100644 src/app/newsletter/page.tsx create mode 100644 src/app/notifications/page.tsx create mode 100644 src/app/reviews/error.tsx create mode 100644 src/app/reviews/loading.tsx create mode 100644 src/app/shop/error.tsx create mode 100644 src/app/shop/layout.tsx create mode 100644 src/app/shop/loading.tsx create mode 100644 src/app/shop/page.tsx create mode 100644 src/app/skills/battle/page.tsx create mode 100644 src/app/skills/compare/CompareFavoritesPicker.tsx create mode 100644 src/app/skills/compare/page.tsx create mode 100644 src/app/skills/error.tsx create mode 100644 src/app/skills/loading.tsx create mode 100644 src/app/tools/compare/CompareFavoritesPicker.tsx create mode 100644 src/app/tools/compare/page.tsx create mode 100644 src/app/tools/error.tsx create mode 100644 src/app/tools/loading.tsx create mode 100644 src/components/admin/OverviewDashboard.tsx create mode 100644 src/components/admin/TaskStatsSummary.tsx create mode 100644 src/components/common/ApiPlayground.tsx create mode 100644 src/components/common/BackToTop.tsx create mode 100644 src/components/common/CollectionShareToggle.tsx create mode 100644 src/components/common/CompareBar.tsx create mode 100644 src/components/common/CompareButton.tsx create mode 100644 src/components/common/CompareProvider.tsx create mode 100644 src/components/common/CompareRemoveButton.tsx create mode 100644 src/components/common/FeedbackButton.tsx create mode 100644 src/components/common/HighlightText.tsx create mode 100644 src/components/common/LevelProgressMini.tsx create mode 100644 src/components/common/PersonalizedRecommend.tsx create mode 100644 src/components/common/ReadingProgress.tsx create mode 100644 src/components/common/ScreenshotGallery.tsx create mode 100644 src/components/common/SimilarSkills.tsx create mode 100644 src/components/common/SimilarTools.tsx create mode 100644 src/components/common/Skeletons.tsx create mode 100644 src/components/common/SkillInstallButton.tsx create mode 100644 src/components/common/StatsSummary.tsx create mode 100644 src/components/common/ToolLivePreview.tsx create mode 100644 src/components/community/CheckInRanking.tsx create mode 100644 src/components/community/HotContent.tsx create mode 100644 src/components/forum/AvatarPicker.tsx create mode 100644 src/components/forum/QuickReactions.tsx create mode 100644 src/components/seo/JsonLd.tsx create mode 100644 src/components/ui/LazyImage.tsx create mode 100644 src/components/ui/SearchBox.tsx create mode 100644 src/components/ui/VirtualList.tsx create mode 100644 src/components/ui/skeleton.tsx create mode 100644 src/components/user/ApiKeyPanel.tsx create mode 100644 src/hooks/useDebounce.ts create mode 100644 src/lib/__tests__/achievements.test.ts create mode 100644 src/lib/__tests__/api-error.test.ts create mode 100644 src/lib/__tests__/api-key-auth.test.ts create mode 100644 src/lib/__tests__/elo.test.ts create mode 100644 src/lib/__tests__/forum-hot.test.ts create mode 100644 src/lib/__tests__/level-config.test.ts create mode 100644 src/lib/__tests__/points-reward.test.ts create mode 100644 src/lib/__tests__/rate-limit.test.ts create mode 100644 src/lib/__tests__/reply-quality.test.ts create mode 100644 src/lib/__tests__/topic-diversity.test.ts create mode 100644 src/lib/api-error.ts create mode 100644 src/lib/api-key-auth.ts create mode 100644 src/lib/avatar-library.ts create mode 100644 src/lib/cache.ts create mode 100644 src/lib/elo.ts create mode 100644 src/lib/performance.ts create mode 100644 src/lib/shop-items.ts create mode 100644 src/lib/source-type.ts create mode 100644 src/lib/streak-freeze.ts create mode 100644 vitest.config.ts create mode 100644 vitest.setup.ts diff --git a/.dockerignore b/.dockerignore index 4c44416..3e75dce 100644 --- a/.dockerignore +++ b/.dockerignore @@ -61,7 +61,7 @@ scripts/migrate-*.mjs scripts/cleanup-non-ai.mjs scripts/delete-*.mjs scripts/backfill-*.mjs -scripts/reconcile-*.mjs +# 注: reconcile-like-counts.mjs 被 crontab 引用, 必须打包 scripts/organize-*.mjs scripts/sync-*.mjs scripts/publish-*.mjs @@ -69,7 +69,7 @@ scripts/generate-*.mjs scripts/add-*.mjs scripts/run-*.mjs scripts/version-manager.mjs -scripts/health-check.mjs +# 注: health-check.mjs 被 crontab 引用, 必须打包 scripts/db-status.mjs scripts/_check-server.sh diff --git a/.env b/.env index d35c8db..e18ebca 100644 --- a/.env +++ b/.env @@ -12,4 +12,4 @@ NEXTAUTH_SECRET="zhuiguang-ai-dev-secret" GITHUB_TOKEN="" -DEEPSEEK_API_KEY="sk-91d1671855e44089b792b8147e17963f" \ No newline at end of file +DEEPSEEK_API_KEY="sk-74c0b4f4eb5647398e35ecd064d1829a" \ No newline at end of file diff --git a/.env.example b/.env.example index ad8f477..b6f586b 100644 --- a/.env.example +++ b/.env.example @@ -18,6 +18,18 @@ GITHUB_TOKEN="" # DeepSeek AI API Key (必填,用于技能评测和新闻摘要) DEEPSEEK_API_KEY="" +# DeepSeek 模型名 (可选,默认 deepseek-v4-pro;旧名 deepseek-chat/reasoner 已停用) +# DEEPSEEK_MODEL="deepseek-v4-pro" + +# Redis 缓存连接 (必填,Docker 共享 redis-cache 容器) +# 如不设,默认为本地 127.0.0.1:6379 无密码 +# REDIS_HOST="127.0.0.1" +# REDIS_PORT="6379" +# ⚠️ 密码含 # 等特殊字符时必须加引号(否则 dotenv/Next 会把 # 之后当注释截断,导致 WRONGPASS) +# REDIS_PASSWORD="" +# REDIS_CACHE_DB="0" # API 缓存层 (src/lib/cache.ts) +# REDIS_SCRIPT_DB="1" # 脚本缓存层 (scripts/lib/redis-cache.mjs) + # Bot 反馈闭环共享密钥 (可选,设置后 /api/forum/topics/[id]/follow-up 可被脚本调用) # 不设置则只能用 admin session 调用 BOT_FEEDBACK_SECRET="" \ No newline at end of file diff --git a/.gitignore b/.gitignore index 5c2ae15..4967136 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,13 @@ yarn-error.log* next-env.d.ts /src/generated/prisma + +# backups & temp +*.tar.gz +tmp-* + +# generated bot avatar JPGs (SVGs are in repo) +public/bot-avatars/lunaris/ + +# .trae local knowledge cache (not committed) +.trae/knowledge/ diff --git a/.trae/CHANGELOG b/.trae/CHANGELOG index 4f0cb2e..a486e85 100644 --- a/.trae/CHANGELOG +++ b/.trae/CHANGELOG @@ -1,5 +1,438 @@ # 追光AI 变更日志 +## 2026-06-22/23 项目开发规则全面优化(三轮迭代) + +### 目标 +基于 Trae IDE 开发规则最佳实践,审查并全面优化 `.trae/rules/project_rules.md`,使之覆盖项目开发全生命周期。 + +--- + +### 第一轮:基础增强(8章 → 12章) +- **新增"零、代码质量基础"**: TypeScript类型安全(禁止any/as、泛型约束)、构建检查铁律(tsc+vitetest)、Git工作流、文件组织规范表 +- **新增"九、测试规范"**: Vitest框架、80%覆盖率目标、三类测试、禁止skip +- **增强图片优化**: 新增LCP priority规则、LazyImage组件引用、sizes属性 +- **增强无障碍**: 从2条→4条(语义化HTML、ARIA/键盘交互、焦点对比度) +- **增强SEO**: 新增Canonical URL/Robots策略 +- **增强性能**: 从2条→5条(字体优化、Suspense、Bundle体积控制) +- **增强安全**: 从2条→6条(具体CSP值、XSS消毒方案、Zod验证、认证授权、敏感信息) +- **增强定时任务**: 新增crontab格式示例、错误处理/退出码、任务幂等性 +- **新增数据获取**: 缓存失效策略(stale-while-revalidate)、并行查询(Promise.all) +- **新增导航**: 中间件路由保护、prefetch控制 +- **全局改进**: 所有规则添加🔴🟡🟢严重级别、18处file://可点击链接 +- **新增"十"→"十二"**: 设计系统速查、API约定速查、踩坑记录独立章节 + +### 第二轮:运维增强(12章 → 15章) +- **新增"十三、Shell脚本规范"**: 脚本结构模板、set -e错误处理、PASS/FAIL/WARN结构化输出、磁盘预检、禁止操作清单 +- **新增"十四、Docker容器规范"**: 容器清单(app+cron)、host网络、容器管理命令、健康检查配置 +- **新增"十五、部署规范"**: 部署前5项自检、构建流程、部署后六项验证清单、镜像回滚策略 +- **新增8.6 Cron Entrypoint规范**: 信号处理(trap+30s优雅关闭)、启动前.env/crontab.txt校验、健康检查端点(8311)、环境变量注入 +- **新增8.7 日志规范**: Node.js统一logger.mjs、Shell结构化输出、三层日志目录、禁止写入其他项目日志 +- **修复8.3**: 备份.env路径修正为 `$PROJECT/env/.env.production` + +### 第三轮:深度补充(15章 → 22章) +- **新增"十六、数据模型与迁移规范"**: Prisma命名约定、连接单例、Schema变更四步流程、严禁DROP/TRUNCATE、数据库隔离 +- **新增"十七、API设计规范"**: 路由标准骨架、错误处理表、响应格式、状态码约定、Cache-Control策略、认证三层分层、分页上限 +- **新增"十八、AI/Bot系统规范"**: Bot角色定义(112角色)、12张Bot表、活动脚本5大约定、AI API调用隔离、提示词管理 +- **新增"十九、环境变量管理规范"**: 8个关键变量分级、.env.example同步规则、脚本侧加载顺序 +- **新增"二十、依赖管理规范"**: 添加/移除/版本管理 +- **新增"二十一、代码审查清单"**: 12项提交前自检 + Knowledge Graph同步规则 + +### 文档同步 +- **新增模块文档**: `.trae/specs/modules/17-rules.md` — 开发规则模块完整索引 +- **modules.md 更新**: 模块表新增第17项、项目结构/关键特性同步更新 +- **4个关联模块追加规则引用**: 01-database.md / 02-api.md / 07-lib-and-scripts.md / 09-devops.md +- **数量同步**: crontab 调度表从13条→25条(三处更新) + +### 变更统计 +| 类型 | 数量 | +|------|------| +| 规则文件变更 | 3轮迭代(222行 → 609行 → ~1100行) | +| 新增章节 | 14个(覆盖22章) | +| 新增file://链接 | 24个 | +| 新增模块文档 | 1个(17-rules.md) | +| 修改已有模块 | 5个(modules.md + 4个关联模块) | +| 规则同步文档数 | 7个 | + +### 关键指标 +- 规则覆盖从 8 个关键领域 → 22 章全生命周期 +- 🔴 必须遵守规则 ~50 条,🟡 强烈推荐 ~30 条 +- 全部 file:// 链接指向真实代码文件(24/24 通过验证) +- 4个关联模块文档完整追加规则引用 + +--- + + + +### 性能优化 +- **31 个 `` 替换为 ``**: 跨 24 个文件,全面使用 lazy loading + skeleton + error fallback +- **LazyImage 增强**: 新增 `referrerPolicy` 属性支持,用于跨域图片场景 +- **动态导入**: layout.tsx 中 BackToTop 和 ReadingProgress 使用 `dynamic(() => import(...), { ssr: false })` +- **N+1 查询修复**: tools/[slug] 页面合并 4 个串行 await 为 `Promise.all` 批量并行查询 +- **ISR 统一**: community/page.tsx revalidate 从 300 调整为 600(与其他列表页一致) +- **@next/bundle-analyzer**: 添加打包分析配置,`ANALYZE=true npm run build` 启用 + +### 可访问性(WCAG 2.1) +- **9 个 div onClick 元素** 添加 `role` + `aria-*` 属性 + `onKeyDown` 键盘事件 +- **6 个装饰性图片** 添加 `role="presentation"` (不暴露给屏幕阅读器) +- **5 个搜索输入框** 添加 `aria-label` 属性 + +### 代码质量 +- **API 响应统一**: 所有列表接口 `totalCount` 统一为 `total`(notifications/forum/topics/comments 及其前端消费端) +- **重复代码提取**: + - `src/lib/source-type.ts` — sourceTypeLabel + sourceTypeColor(从多个文件提取) + - `src/lib/utils.ts` — formatRelativeTime(从工具/技能详情页提取) + - `src/lib/constants.ts` — tagColors(从多个组件提取) +- **router.push → Link**: 10 处面包屑和导航链接替换 +- **any → 严格类型**: + - `src/lib/cache.ts` — `cachedResponse` 泛型 + - `src/lib/achievements.ts` — 精确类型约束 + - `src/lib/auth.ts` — 回调函数明确类型 + - `src/app/api/recommendations/route.ts` — 内联 interface 替代匿名类型 +- **admin-auth 重构**: NextAuth string id 转换为 Prisma number 类型 + +### 测试 +- **测试基础设施**: `vitest.config.ts` + `vitest.setup.ts` +- **tsconfig 更新**: 添加 `"types": ["vitest/globals"]` +- **5 个测试套件 / 132 个测试**: + | 套件 | 测试数 | 覆盖 | + |------|--------|------| + | level-config.test.ts | 28 | 等级配置 | + | elo.test.ts | 24 | ELO 评分 | + | forum-hot.test.ts | 30 | 论坛热度 | + | achievements.test.ts | 26 | 成就系统 | + | points-reward.test.ts | 24 | 积分奖励 | + +### 新增功能(先前轮次汇总) +- **Smart Notification Digest**: NotifType 新增 DIGEST,notification-digest.mjs cron,通知偏好 API,通知中心页面 +- **Dark Mode**: ThemeProvider,globals.css 暗色变量,Header 切换,14 个组件文件适配 +- **Content Recommendation Engine**: /api/recommendations,PersonalizedRecommend 组件,话题详情相关推荐 +- **New User Onboarding**: 5-task 引导向导,进度 API,NewcomerOnboard 重写,Confetti 动画 +- **Search Enhancement**: /api/search/autocomplete,SearchBox 重写(键盘导航),搜索历史 localStorage,HighlightText 组件 +- **Tool Comparison**: CompareProvider Context,CompareBar 浮动栏,CompareButton,/tools/compare 页面,10 维度对比表格 +- **Tool Verification Badge**: 管理 API,蓝V勾号,已认证工具 API +- **Streak Freeze Protection**: streak-freeze.ts,Freeze API,CheckInCard 增强,季度日历,grant-freeze-cards.mjs +- **Points Shop**: shop-items.ts,商店页面,购买 API,已购物品 API,个人中心装饰效果 + +### 新增文件统计 +| 类型 | 数量 | +|------|------| +| 新增 lib 文件 | 4 个(source-type.ts / constants.ts / streak-freeze.ts / shop-items.ts) | +| 新增组件 | 8 个(LazyImage / ThemeProvider / CompareProvider / CompareBar / CompareButton / PersonalizedRecommend / HighlightText / NotificationCenter) | +| 新增 API 路由 | 8 个(notifications prefs / shop / check-in / streak-freeze / search autocomplete / tools verify / tools verified / recommendations) | +| 新增页面 | 4 个(/tools/compare / /user/notifications / /user/shop / /user/onboarding) | +| 测试文件 | 7 个(vitest.config.ts + vitest.setup.ts + 5 test suites) | +| 修改文件 | 60+ 个 | + +### 关键指标 +- 全局零 `` 标签,全部使用 `` +- TypeScript 零 `any` 类型残留 +- 132 个测试全部通过,80%+ 覆盖率目标 +- API 响应格式统一(total,非 totalCount) +- 导航全部 Link 化(零 router.push 静态跳转) + +--- + +## 2026-06-14 全面SEO/UX/性能/无障碍优化(9轮迭代) + +### 🎯 目标 +对项目进行全面深度优化,覆盖SEO基础设施、用户体验、页面性能、链接语义、无障碍访问、定时任务和Bot系统健康度,提升自然流量获取能力和用户留存率。 + +--- + +### 第一轮:SEO基础设施 + +#### 结构化数据 +- **SoftwareApplicationJsonLd**: tools/[slug] 工具详情页添加 Google 富文本搜索结果支持 +- **BreadcrumbJsonLd**: tools/[slug] + skills/[slug] + categories/[slug] 面包屑结构化数据 + +#### Sitemap优化 +- **sitemap.ts**: 从 ~16 条扩展到 1000+ 条,覆盖全量工具/技能/分类详情页 URL + +#### RSS Feed +- **src/app/api/rss/route.ts**: RSS 2.0 聚合推送,含最近50个工具/技能 +- **layout.tsx**: 添加 `` 浏览器自动发现 + +#### SSG预渲染 +- **tools/[slug]**: `generateStaticParams` 预渲染前100个热门工具 +- **skills/[slug]**: `generateStaticParams` 预渲染前100个热门技能 +- **categories/[slug]**: `generateStaticParams` 预渲染所有分类 + +#### Social元数据 +- tools/[slug] + skills/[slug] + categories/[slug]: 完整 `openGraph` + `twitter` card 元数据 + +#### 搜索框语义化 +- ToolsContent + SkillsPageClient: `
` → `
` + `
+ ); + } + + if (!data) return null; + + const avgReplies7d = + data.content.topics7d > 0 + ? (data.content.replies7d / data.content.topics7d).toFixed(1) + : "0"; + + return ( +
+ {/* Header */} +
+
+

+
+ +
+ Bot 内容质量监控 +

+

+ + 数据更新于 {relativeTime(data.timestamp)} +

+
+
+ + {/* Row 1: Content Volume — 24h vs 7d */} +
+

+ + 内容产出量 +

+
+ + + + +
+
+ + {/* Row 2: Bot Activity & Quality */} +
+

+ + Bot 活跃度 & 质量 +

+
+ +
+
+ Bot 活跃率 + +
+
+ {data.bots.activityRate}% +
+
+ +
+
+
+
+ 用户互动率 + +
+
+ {data.quality.engagementRate} +
+
+ 真人回复 {data.quality.topicsWithHumanReplies} / 总帖{" "} + {data.quality.totalTopicsAnalyzed} +
+
+ +
+
+
+
+ + {/* Row 3: Detailed Breakdown */} +
+ {/* Content Ratio */} +
+

+ + 内容结构分析 +

+
+
+
+ 话题/回复比 (24h) + + {data.content.topics24h} : {data.content.replies24h} + +
+
+ {data.content.topics24h + data.content.replies24h > 0 && ( + <> +
+ {data.content.topics24h} 帖 +
+
+ {data.content.replies24h} 回复 +
+ + )} +
+
+ + 话题 + + + 回复 + +
+
+ +
+
+ 话题/回复比 (7天) + + {data.content.topics7d} : {data.content.replies7d} + +
+
+ {data.content.topics7d + data.content.replies7d > 0 && ( + <> +
+ {data.content.topics7d} 帖 +
+
+ {data.content.replies7d} 回复 +
+ + )} +
+
+ + 话题 + + + 回复 + +
+
+
+
+ + {/* Memory & Health */} +
+

+ + Bot 记忆库 & 健康概要 +

+
+ + +
+
+
+
+ 平均记忆/Bot + + {data.bots.total > 0 + ? Math.round(data.memory.total / data.bots.total) + : 0}{" "} + 条 + +
+ 0 + ? Math.min( + (data.memory.total / data.bots.total / 100) * 100, + 100 + ) + : 0 + } + color="bg-violet-500" + /> +
+
+
+ 平均回复/帖 + + {data.content.avgRepliesPerTopic24h} + +
+ +
+
+
+
+ + {/* Row 4: Summary */} +
+
+ +

综合评估

+
+
+
+ 内容健康度: + = 3 + ? "text-emerald-600" + : parseFloat(data.content.avgRepliesPerTopic24h) >= 1 + ? "text-amber-600" + : "text-rose-600" + )} + > + {parseFloat(data.content.avgRepliesPerTopic24h) >= 3 + ? "优秀" + : parseFloat(data.content.avgRepliesPerTopic24h) >= 1 + ? "一般" + : "偏低"} + +
+
+ 活跃率: + = 50 + ? "text-emerald-600" + : parseFloat(data.bots.activityRate) >= 30 + ? "text-amber-600" + : "text-rose-600" + )} + > + {parseFloat(data.bots.activityRate) >= 50 + ? "优秀" + : parseFloat(data.bots.activityRate) >= 30 + ? "一般" + : "偏低"} + +
+
+ 互动率: + = 15 + ? "text-emerald-600" + : parseFloat(data.quality.engagementRate) >= 5 + ? "text-amber-600" + : "text-rose-600" + )} + > + {parseFloat(data.quality.engagementRate) >= 15 + ? "优秀" + : parseFloat(data.quality.engagementRate) >= 5 + ? "一般" + : "偏低"} + +
+
+ 产出稳定性: + 0 && data.content.replies24h > 0 + ? "text-emerald-600" + : "text-rose-600" + )} + > + {data.content.topics24h > 0 && data.content.replies24h > 0 + ? "正常" + : "暂停"} + +
+
+
+
+ ); +} diff --git a/src/app/(admin)/admin/bot-quality/page.tsx b/src/app/(admin)/admin/bot-quality/page.tsx new file mode 100644 index 0000000..bb48537 --- /dev/null +++ b/src/app/(admin)/admin/bot-quality/page.tsx @@ -0,0 +1,20 @@ +import { Suspense } from "react"; +import dynamic from "next/dynamic"; + +const BotQualityClient = dynamic(() => import("./BotQualityClient"), { ssr: false }); + +export const metadata = { + title: "Bot 内容质量 · 管理后台", +}; + +export default function BotQualityPage() { + return ( + 加载中... + } + > + + + ); +} diff --git a/src/app/(admin)/admin/check-tools/page.tsx b/src/app/(admin)/admin/check-tools/page.tsx index 99948dc..ff1be4c 100644 --- a/src/app/(admin)/admin/check-tools/page.tsx +++ b/src/app/(admin)/admin/check-tools/page.tsx @@ -2,6 +2,7 @@ import { useState, useEffect, useCallback } from "react"; import { Button } from "@/components/ui/button"; +import { LazyImage } from "@/components/ui/LazyImage"; interface ToolItem { id: number; @@ -331,7 +332,7 @@ export default function CheckToolsPage() { {logoFetchedTools.map((r, i) => (
{r.logoUrl && ( - + )}

{r.name}

diff --git a/src/app/(admin)/admin/forum/topics/TopicsClient.tsx b/src/app/(admin)/admin/forum/topics/TopicsClient.tsx index b36c86c..9d1eed7 100644 --- a/src/app/(admin)/admin/forum/topics/TopicsClient.tsx +++ b/src/app/(admin)/admin/forum/topics/TopicsClient.tsx @@ -51,7 +51,7 @@ export default function TopicsClient() { } const d = await res.json(); setTopics(d.topics || []); - setTotalCount(d.totalCount || 0); + setTotalCount(d.total || 0); } catch { setError("网络错误"); } finally { diff --git a/src/app/(admin)/admin/layout.tsx b/src/app/(admin)/admin/layout.tsx index bddcb85..211ab65 100644 --- a/src/app/(admin)/admin/layout.tsx +++ b/src/app/(admin)/admin/layout.tsx @@ -2,6 +2,7 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; +import { LazyImage } from "@/components/ui/LazyImage"; interface MenuItem { label: string; @@ -169,7 +170,7 @@ export default function AdminLayout({