Jass Space is a personal web platform made of a Next.js frontend and a .NET API backend. It powers public content pages, gallery and music browsing, blog content, user accounts, admin tools, contact flows, comments, likes, search, and email workflows.
| Area | Details |
|---|---|
| Frontend | Next.js, React, TypeScript, Tailwind CSS |
| Backend | .NET 10, ASP.NET Core, Entity Framework Core |
| Database | PostgreSQL |
| Cache | Redis |
| Background jobs | Hangfire |
| Auth | JWT, refresh tokens, Google OAuth, GitHub OAuth |
| Deployment | Docker Compose and GitHub Actions |
| Main local ports | UI 3001, API 5001 |
.
|-- api/ # .NET solution, API, services, data, tests
| |-- JassSpace.Api/ # ASP.NET Core entrypoint and controllers
| |-- JassSpace.Contracts/ # Request/response DTOs and interfaces
| |-- JassSpace.Data/ # DbContext and EF Core migrations
| |-- JassSpace.Entities/ # Domain entities
| |-- JassSpace.Infra/ # Email, cache, storage, and infrastructure services
| |-- JassSpace.Repositories/ # Data access layer
| |-- JassSpace.Services/ # Business logic
| `-- JassSpace.Tests/ # xUnit tests
|-- ui/ # Next.js application
| |-- app/ # App Router pages and routes
| |-- components/ # Shared UI components
| |-- lib/ # API clients, helpers, cache utilities
| `-- public/ # Static assets
|-- .github/workflows/ # Deployment and maintenance workflows
|-- docker-compose.yml # Base Compose stack
|-- docker-compose.prod.yml # Production Compose overrides
`-- .env.example # Environment variable template
- Public portfolio-style pages for services, projects, blog, gallery, music, uses, and contact.
- Authenticated account area with profile, security, preferences, and OAuth support.
- Admin dashboard for content, blog, gallery, music, email, users, and settings.
- Blog and gallery content backed by the API, with search and pagination patterns in the UI.
- Comments, likes, public user profiles, and anonymous content view tracking.
- Email templates, SMTP delivery, contact handling, and background jobs.
- Dockerized API and UI services with production-oriented resource limits.
- Node.js 20 or newer.
- npm.
- .NET SDK
10.0.101or a compatible latest feature roll-forward version. - Docker and Docker Compose for containerized runs.
- PostgreSQL and Redis for local non-container development.
The .NET SDK version is controlled by api/global.json.
Copy the example environment file and fill in local values:
Copy-Item .env.example .envImportant groups in .env.example:
ConnectionStrings__DefaultConnectionfor PostgreSQL.ConnectionStrings__Redisfor Redis.NEXT_PUBLIC_API_URL,NEXT_PUBLIC_APP_URL, andNEXT_PUBLIC_SITE_URLfor the frontend.JWT__*for authentication tokens.OAuth__Google__*andOAuth__GitHub__*for OAuth login.Email__Smtp__*for email delivery.Hangfire__DashboardAuth__*for the Hangfire dashboard.
Do not commit real .env files. The root .gitignore already ignores .env.
cd api
dotnet restore JassSpace.sln
dotnet run --project JassSpace.ApiThe API is exposed by Docker Compose on port 5001. Direct dotnet run settings depend on the API launch profile and local configuration.
cd ui
npm install
npm run devThe Next.js dev server runs on:
http://localhost:3001
docker compose up -d --buildThe base Compose stack starts:
dotneton host port5001nextjson host port3001
Production overrides can be applied with:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --buildRun migration commands from the api folder.
dotnet ef migrations add "Migration Name" --project JassSpace.Data --startup-project JassSpace.Apidotnet ef database update --project JassSpace.Data --startup-project JassSpace.ApiWhen the API starts through Docker Compose, pending EF Core migrations can be applied automatically by ApplyMigrationsOnStartup.
- Base Compose default:
APPLY_MIGRATIONS=false - Production override default:
APPLY_MIGRATIONS=true
dotnet restore api/JassSpace.sln
dotnet build api/JassSpace.sln --configuration Release
dotnet test api/JassSpace.sln --configuration Releasenpm --prefix ui ci
npm --prefix ui run lint
npm --prefix ui run buildUse npm.cmd --prefix ui ... on Windows if PowerShell blocks the npm shim.
Deployment is handled through GitHub Actions and Docker Compose.
.github/workflows/deploy-dotnet.ymlvalidates, tests, and deploys the .NET service when API or Compose files change onmain..github/workflows/deploy-nextjs.ymlvalidates, lints, builds, and deploys the Next.js service when UI or Compose files change onmain..github/workflows/refresh-containers.ymlmanually recreates containers on the production server.
The dotnet and Next.js deploy workflows share the same GitHub Actions concurrency group:
jassspace-production-deploy
The remote deployment scripts also use a shared .deploy.lock file so production deployments run serially.
Required GitHub deployment secrets:
SSH_HOSTSSH_PORTSSH_USERREMOTE_DIRSSH_PRIVATE_KEY
Recommended branch usage:
devis the integration branch for active work.mainis the production branch.- Merge
devintomainwhen validated changes are ready for deployment. - Push both branches when they are expected to stay in sync.
For feature work, prefer short-lived branches from dev, then merge back into dev before promoting to main.
The root version.json file is the source of truth for the independently released component versions and names:
- The UI is named
sw-lavenderand has its own semantic version. - The API is named
sw-juniperand has its own semantic version. - Changing one component does not increment the other component.
Check that the shared manifest and UI package metadata agree:
node scripts/bump-version.mjs checkPrepare a release by selecting the component and incrementing exactly one part:
node scripts/bump-version.mjs ui patch
node scripts/bump-version.mjs ui minor
node scripts/bump-version.mjs api patch
node scripts/bump-version.mjs api majorUse patch for compatible fixes, minor for new functionality, and major for breaking component changes. A UI bump synchronizes its package metadata; an API bump synchronizes its .NET project metadata. The UI embeds its identity during its build, and the API publishes the shared manifest with its output and exposes its identity at /version.
See Component Versioning for the complete command reference, examples, component tags, and release workflow.
# Check current branch and local changes
git status --short --branch
# Build the API
dotnet build api/JassSpace.sln
# Run API tests
dotnet test api/JassSpace.sln
# Lint the UI
npm.cmd --prefix ui run lint
# Build the UI
npm.cmd --prefix ui run build
# Start both services with Docker Compose
docker compose up -d --build- Keep real secrets in local
.envfiles or GitHub Actions secrets. - Keep public-facing content truthful and safe to expose.
- Prefer shared UI components and shared service paths over page-local one-off logic.
- When changing deployment behavior, verify both the GitHub Actions workflow and the remote Docker Compose path.