Skip to content
ZhouJunzPublic

About

个人博客

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

SkillTree Blog

A FastAPI + React + Vite blog and admin console. It supports public posts, user accounts, author pages, review workflow, admin statistics, comments, operation logs, tags, site settings, and local development seed data.

Stack

  • Backend: FastAPI, SQLAlchemy, SQLite
  • Frontend: React, TypeScript, Vite
  • Tests: pytest

Project Layout

app/
  core/              # Configuration
  db/                # SQLAlchemy session, models, bootstrap/migrations
  routes/            # FastAPI route modules
  services/          # Business services
  static/            # Legacy static assets
  templates/         # Legacy Jinja templates
frontend/
  src/               # React application
  admin.html         # Admin console entry
  index.html         # Public site entry
scripts/
  seed_fake_data.py  # Local development data generator
tests/
  test_health.py     # API regression tests

Environment

Copy .env.example to .env if you want to override defaults:

APP_NAME=SkillTree Blog
APP_ENV=development
CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173
ADMIN_USERNAME=admin
ADMIN_PASSWORD=skilltree123
SECRET_KEY=please-change-this-secret
DATABASE_URL=sqlite:///data/skilltree.sqlite3
AVATAR_UPLOAD_DIR=app/static/uploads/avatars
CARD_BACKGROUND_UPLOAD_DIR=app/static/uploads/card-backgrounds
POST_ASSET_UPLOAD_DIR=app/static/uploads/post-assets

Default admin account:

  • Username: admin
  • Password: skilltree123

Change ADMIN_PASSWORD and SECRET_KEY before using this outside local development.

Production startup validates the critical settings when APP_ENV=production:

  • SECRET_KEY must be changed and contain at least 32 characters.
  • ADMIN_PASSWORD must be changed and contain at least 12 characters.
  • CORS_ORIGINS must be explicit and cannot contain *.
  • DATABASE_URL must point to a persistent database.
  • AVATAR_UPLOAD_DIR, CARD_BACKGROUND_UPLOAD_DIR, and POST_ASSET_UPLOAD_DIR control where uploaded avatars, background materials, and post body images are stored.

Example production-style values:

APP_ENV=production
CORS_ORIGINS=https://your-domain.example
ADMIN_PASSWORD=replace-with-a-long-random-password
SECRET_KEY=replace-with-at-least-32-random-characters
DATABASE_URL=sqlite:////opt/skilltree/data/skilltree.sqlite3
AVATAR_UPLOAD_DIR=/opt/skilltree/app/static/uploads/avatars
CARD_BACKGROUND_UPLOAD_DIR=/opt/skilltree/app/static/uploads/card-backgrounds
POST_ASSET_UPLOAD_DIR=/opt/skilltree/app/static/uploads/post-assets

Run Locally

Backend:

E:\Anaconda3\envs\SkillTree\python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8000

Frontend:

cd frontend
npm install
npm run dev -- --host 127.0.0.1

Open:

  • Public site: http://127.0.0.1:5173/
  • Admin console: http://127.0.0.1:5173/admin.html
  • Health check: http://127.0.0.1:8000/health

Seed Fake Data

Generate repeatable local development data:

E:\Anaconda3\envs\SkillTree\python.exe scripts\seed_fake_data.py

The script resets and recreates:

  • Development users: dev_author_alice, dev_author_bob, dev_author_disabled
  • Development content with dev-sample-* slugs
  • Comments for moderation
  • Tags for the tag manager

Tests And Build

Backend tests:

E:\Anaconda3\envs\SkillTree\python.exe -m pytest

Frontend build:

cd frontend
npm run build

Tests use an isolated temporary SQLite database through tests/conftest.py, so they do not mutate data/skilltree.sqlite3.

Database Setup And Migration

Create or upgrade the database tables and seed the default admin account/categories:

E:\Anaconda3\envs\SkillTree\python.exe scripts\manage_db.py upgrade --seed

Check which schema migrations have already been applied:

E:\Anaconda3\envs\SkillTree\python.exe scripts\manage_db.py status

The deploy scripts run upgrade --seed automatically before starting services. The migration command is safe to run repeatedly; applied versions are tracked in the schema_migrations table.

Backup And Restore

Create a backup zip containing the SQLite database, uploaded avatars, background materials, post body assets, and a manifest:

E:\Anaconda3\envs\SkillTree\python.exe scripts\backup_data.py backup

Restore from a backup:

E:\Anaconda3\envs\SkillTree\python.exe scripts\backup_data.py restore backups\skilltree-backup-YYYYMMDD-HHMMSS.zip --yes

Restore replaces the current database and upload directories. By default it first creates a safety backup in backups/; add --no-safety-backup only if you already made a separate copy. Stop the running backend before restoring production data.

Smoke Check

After starting the backend, run a quick API smoke check:

E:\Anaconda3\envs\SkillTree\python.exe scripts\smoke_check.py

The script verifies health check, admin login, public posts, admin stats, tags, comments, logs, and settings.

One-Command Local Deploy

For a single Windows machine or small server, use the deploy script to test, build, restart services, and run smoke checks:

powershell.exe -ExecutionPolicy Bypass -File scripts\deploy.ps1 -Python "E:\Anaconda3\envs\SkillTree\python.exe"

Default ports:

  • Backend: http://127.0.0.1:8000
  • Frontend production preview: http://127.0.0.1:4173

Useful options:

# Build and test only, do not start services
powershell.exe -ExecutionPolicy Bypass -File scripts\deploy.ps1 -NoStart

# Skip tests when doing a quick restart
powershell.exe -ExecutionPolicy Bypass -File scripts\deploy.ps1 -SkipTests

# Seed local fake data before starting
powershell.exe -ExecutionPolicy Bypass -File scripts\deploy.ps1 -SeedFakeData

# Expose services on all interfaces for LAN/server use
powershell.exe -ExecutionPolicy Bypass -File scripts\deploy.ps1 -BackendHost 0.0.0.0 -FrontendHost 0.0.0.0

Logs are written to logs/backend.*.log and logs/frontend.*.log.

Linux Server Deploy

On Linux, the Bash deploy script can create/update a virtualenv, install Python and Node dependencies, run database migrations, verify writable upload/data directories, run tests, build the frontend, restart services, and run smoke checks:

chmod +x scripts/deploy.sh
BACKEND_HOST=0.0.0.0 FRONTEND_HOST=0.0.0.0 scripts/deploy.sh

Prerequisites:

  • Python 3.11+
  • Node.js and npm
  • curl
  • lsof or ss for stopping existing processes on the target ports

Common options:

# Install dependencies, test, and build only
scripts/deploy.sh --no-start

# Quick restart without tests
scripts/deploy.sh --skip-tests

# Seed fake data before starting
scripts/deploy.sh --seed-fake-data

# Use a specific Python executable
PYTHON_BIN=python3.11 scripts/deploy.sh

The Linux script uses .venv by default. Override with SKILLTREE_VENV_DIR=/path/to/venv.

Main API Areas

Public:

  • GET /health
  • GET /api/posts
  • GET /api/posts?type=article&q=keyword&date=2026-04-24
  • GET /api/posts/{slug}
  • GET /api/authors/{username}

Auth:

  • POST /api/auth/login
  • POST /api/auth/register
  • GET /api/auth/me
  • PATCH /api/auth/me

Content:

  • GET /api/me/posts
  • GET /api/me/posts/{slug}
  • POST /api/me/posts/{slug}/withdraw
  • GET /api/admin/posts
  • POST /api/admin/posts
  • PATCH /api/admin/posts/{slug}
  • DELETE /api/admin/posts/{slug}
  • POST /api/admin/posts/{slug}/review

Admin:

  • GET /api/admin/stats
  • GET /api/admin/users
  • PATCH /api/admin/users/{user_id}
  • DELETE /api/admin/users/{user_id}
  • GET /api/admin/comments
  • PATCH /api/admin/comments/{comment_id}
  • DELETE /api/admin/comments/{comment_id}
  • GET /api/admin/logs
  • GET /api/admin/tags
  • POST /api/admin/tags
  • PATCH /api/admin/tags/{tag_id}
  • DELETE /api/admin/tags/{tag_id}
  • GET /api/admin/settings
  • PUT /api/admin/settings

Notes

  • Deleting users performs a soft delete and keeps content author references intact.
  • Public posts only include status=published and visibility=public.
  • Author-created content goes through draft -> pending -> published/rejected/archived.
  • Admin stats and dashboard charts are backed by real API data.

About

个人博客

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages