尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证ArborKin is a full-stack family tree application designed to help extended families reconnect and pre serve their stories. Built with Blazor Server, C# 13, EF Core, and SQL Server, it provide s an interactive canvas for visualizing genealogy, sharing family memories, and maintaining a permanent record of relationships across generations.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Built by Douglas Rosenberg — full-stack .NET software engineer. See the portfolio write-up and technical blog post on ArborKin's tree layout engine, drag-state handling, and photo upload architecture.
ArborKin is a full-stack family tree application designed to help extended families reconnect and preserve their stories. Built with Blazor Server, C# 13, EF Core, and SQL Server, it provides an interactive canvas for visualizing genealogy, sharing family memories, and maintaining a permanent record of relationships across generations.查看完整 README ↗Built by Douglas Rosenberg — full-stack .NET software engineer. See the portfolio write-up and technical blog post on ArborKin's tree layout engine, drag-state handling, and photo upload architecture.
ArborKin is a full-stack family tree application designed to help extended families reconnect and preserve their stories. Built with Blazor Server, C# 13, EF Core, and SQL Server, it provides an interactive canvas for visualizing genealogy, sharing family memories, and maintaining a permanent record of relationships across generations.
The application prioritizes privacy first — families control their own data, invited members can contribute stories and photos, and an audit log ensures complete accountability. The architecture emphasizes reliability through constraints: comprehensive tests, strict type safety, and database integrity validation catch bugs before production deployment.
Key technical highlights:
Designed as both a genuine family tool (actively used by 5+ family members) and a portfolio piece demonstrating professional full-stack .NET development.
| Metric | Status |
|---|---|
| Core Tests | 287/287 ✅ |
| Web Tests (components, layout, services) | 328/333 ✅ (5 skipped) |
| E2E Tests (Playwright, real SQL Server) | 18/18 ✅ |
| Total | 633 passing (as of 2026-10-25) |
| Build (Debug + Release) | ✅ |
| CI Pipeline | ✅ View Latest Run |
| Branch Protection | ✅ Master requires PR + passing CI |
This project serves three intertwined goals: practical, educational, and professional.
Practically, it's a real tool for a real family. Building software for people you know (rather than hypothetical users) forces you to prioritize genuine usability and reliability. Every feature shipped must work correctly the first time — there's no room for tutorial-code shortcuts.
Educationally, it's a deliberate deep-dive into full-stack .NET development. Specifically: relational database design (schema evolution, migration sequencing, scoping strategies, cascade behavior), exploratory testing discipline (understanding when automated tests suffice and when manual testing catches things machines miss), and the architectural decisions that keep code maintainable as complexity grows.
Professionally, it's an end-to-end portfolio piece: not a tutorial clone or toy project, but a production-ready application with comprehensive tests, security constraints, role-based access control, and actual deployment infrastructure. It demonstrates the ability to ship a complete system, not just write code that passes a code review.
Interactive pan/zoom canvas with SVG connectors and draggable focus overlay.
Dark mode with glass-morphism surfaces and token-driven theme.
Edit / delete actions while tree remains interactive behind the drawer.
Shared form for create/update with date validation and photo uploads.
Stats, quick actions, activity feed, export options.
Invite management, user roles, linked-person assignment, audit log.
docs/blogs/Technical Blog — Deep-dive articles on architectural decisions and lessons learned:
Canvas & Tree
FamilyTreeLayoutEngine — all node (X, Y) positions calculated server-side before render; no DOM measurementlocalStorage; SSR flash prevention via _ready flagAuth & Security
Open, InviteOnly (production default), Closed; a missing or unrecognised setting fails closed to InviteOnlyAppUser.IsAdmin), set by the site owner from the Users tabICurrentUserService interface in Core, implemented in Web — no HttpContext in the service layerMulti-tenant Family Isolation
FamilyId claim baked into auth cookie at sign-inCreatedBy, UpdatedBy, DeletedBy, FamilyId) stamped on every writeAdmin Panel
Data
Person, Relationship, Medium — global EF query filtersRelationship canonical ordering: lower Guid is always PersonAId; unique DB constraint prevents duplicatesRelationship.IsEnded / EndDate distinguish active from former spouses; an ended marriage with no known date stays undatedPeople, Relationships, AuditLogsMigrateAsync()Media & Export
/media/..., only to the person's own family, so the container can stay privateCI/CD
workflow_dispatchSingle-service design — no HTTP boundary between UI and data layer:
FamilyTree.Web (Blazor Server + MudBlazor — Azure App Service B1)
↓ direct service injection
FamilyTree.Core (Service layer + EF Core)
↓
SQL Server (local SQLEXPRESS) / Azure SQL Database (prod)
Projects:
FamilyTree.Shared — DTOs and enums; no logic; shared by Core and WebFamilyTree.Core — Services, EF Core, blob storage, migrationsFamilyTree.Web — Blazor Server UI; injects IPersonService etc. directlyKey design decisions are documented in docs/ (ADR 001: JS-free layout engine, relationship canonical ordering, cross-root couple layout, SSR flash prevention).
Confidence in code comes from rigorous constraints, not subjective review. This project follows Uncle Bob Martin's approach: surround agents (and developers) with a gauntlet of automated checks that catch bugs early.
Constraints in place:
dotnet build + dotnet test must pass on every push (no manual override path)Result: The test suite is comprehensive enough that human code review is optional — if code passes the gauntlet, it works.
| Test Type | Framework | Runs | Command |
|---|---|---|---|
| Unit / integration (Core services) | xUnit + FluentAssertions, EF Core InMemory, real UserManager | ✅ CI on every PR | dotnet test FamilyTree.sln |
| Component + layout (Blazor, layout engines) | bUnit, CsCheck property tests | ✅ CI on every PR | dotnet test FamilyTree.sln |
| E2E (real browser, real app process) | Playwright + SQL Server | ✅ CI on every PR (own job) | dotnet test tests/FamilyTree.E2E.Tests |
Unit, integration and component tests: in-memory EF Core with each test on its own database. Highlights:
CrossTenantMatrixTests: every public method of the family-scoped services, called from one family against another's IDs, must fail or return nothingFamilyTreeLayoutFuzzTests / FamilyTreeLayoutTransitionTests: property tests and before/after edit pairs for the layout enginesPlausibilityRulesTests, EntryGuardrailServiceTests: date sanity rules shared by the server and the formAdminUserServiceTests, SecurityStampRevalidationTests, LoginRedirectTests: session revocation and sign-in redirects[Trait("Category", "Regression")]E2E tests: launch the built app against a disposable SQL Server database and drive it with headless Chromium: invite-to-tree signup, the story-invite journey under invite-only registration on a desktop and a phone, CSRF on login/logout, session revocation, sign-in deep links, mobile layout. The security-stamp check runs on every request in every E2E test. Locally they need SQL Server Express (E2E_ConnectionString overrides the default) and a trusted dev certificate (dotnet dev-certs https --trust).
# Everything, including E2E (needs local SQL Server)
dotnet build FamilyTree.sln
dotnet test FamilyTree.sln
# Only the tests for bugs found live
dotnet test FamilyTree.sln --filter "Category=Regression"
The login rate limit (5 per 15 minutes per IP) applies to E2E runs too: running the E2E suite several times in a row can fail with ?loginError=toomany.
FamilyTree/
├── src/
│ ├── FamilyTree.Shared/ # DTOs, enums (no logic)
│ ├── FamilyTree.Core/ # Services, EF Core, migrations, blob storage
│ └── FamilyTree.Web/ # Blazor Server UI, auth endpoints
│ ├── Components/ # Canvas, PersonNode, drawers, dialogs, admin
│ ├── Services/ # CurrentUserService, ThemeService, etc.
│ └── wwwroot/ # CSS, JS (canvas-interaction.js only)
├── tests/
│ ├── FamilyTree.Core.Tests/ # Service-layer tests (xUnit + InMemory EF)
│ └── FamilyTree.Web.Tests/ # Component tests (bUnit)
├── docs/ # ADRs, build plan, deployment, next steps
└── .github/workflows/ # ci.yml (test on push), deploy-web.yml (manual)